diff --git a/.github/workflows/test-config.yml b/.github/workflows/test-config.yml index e5f805b..45d4854 100644 --- a/.github/workflows/test-config.yml +++ b/.github/workflows/test-config.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: true matrix: - php: [ '7.4', '8.0', '8.1', '8.2', '8.3' ] + php: [ '8.0', '8.1', '8.2', '8.3' ] l5-swagger-flags: ['latest', 'swagger-php-3', 'swagger-ui-3'] name: PHP ${{ matrix.php }} - ${{ matrix.l5-swagger-flags }} @@ -66,8 +66,13 @@ jobs: ./cc-test-reporter before-build if: matrix.php == '8.3' && matrix.l5-swagger-flags == 'latest' + - name: Run PHP 8.0 test suite + run: vendor/bin/phpunit --testdox -c phpunit-php80.xml + if: matrix.php == '8.0' + - name: Run test suite run: composer run-script phpunit + if: matrix.php != '8.0' - name: Publish code coverage env: diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 641f526..0000000 --- a/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -language: php -sudo: false -git: - depth: 1 -env: - global: - - DEFAULT_COMPOSER_FLAGS="--no-interaction --no-progress --optimize-autoloader" - - REPORT_TESTS_COVERAGE=0 - - CACHE_NAME=OPEN_API -matrix: - fast_finish: true - include: - - php: 7.2 - - php: 7.3 - - php: 7.4 - env: - - REPORT_TESTS_COVERAGE=1 - - XDEBUG_MODE=coverage - - php: 8.0 -cache: - directories: - - "$HOME/.composer/cache" -install: - - travis_retry composer update $DEFAULT_COMPOSER_FLAGS - - composer require 'zircote/swagger-php:3.*' - - composer info -D | sort -before_script: - - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - - chmod +x ./cc-test-reporter - - ./cc-test-reporter before-build -script: - - pwd - - ls -al | grep $USER - - sudo chown -R $USER:$USER . - - sudo chmod -R g+rw . - - ls -al | grep $USER - - mkdir -p tests/storage/logs/test-reports - - mkdir -p vendor/orchestra/testbench-core/laravel/vendor/swagger-api - - mkdir -p vendor/orchestra/testbench-core/laravel/vendor/swagger-api/swagger-ui - - mkdir -p vendor/orchestra/testbench-core/laravel/vendor/swagger-api/swagger-ui/dist - - sudo chown -R $USER:$USER vendor/orchestra/testbench-core/laravel/vendor/swagger-api - - chmod -R 777 vendor/orchestra/testbench-core/laravel/vendor/swagger-api - - ls -al vendor/orchestra/testbench-core/laravel/vendor/swagger-api - - chmod -R 777 /home/travis/build/DarkaOnLine/L5-Swagger - - if [ $REPORT_TESTS_COVERAGE != 1 ]; then vendor/bin/phpunit --no-coverage; fi - - if [ $REPORT_TESTS_COVERAGE == 1 ]; then vendor/bin/phpunit; cp tests/storage/logs/test-reports/clover.xml clover.xml; fi - - ls -al vendor/orchestra/testbench-core/laravel/vendor/swagger-api/swagger-ui/dist -after_success: - - if [ $REPORT_TESTS_COVERAGE == 1 ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then ./cc-test-reporter after-build -t clover --exit-code $TRAVIS_TEST_RESULT; fi - - if [ $REPORT_TESTS_COVERAGE == 1 ]; then php vendor/bin/php-coveralls -v; fi -notifications: - email: false - slack: - secure: ZymO41QYmcBtaqIcjKagifif5bH+vpUdZe9eN2Q27G2HF7ID0ZP2X6sCCUCVqdJfM3DhmEsNo8h/HiY86u/5zhf5YpZr7vt+CuYinIJ+nydGXWO5CU6nSotmafFgo3u+Yyjz6qIBhnOVZL8prYcbZsn0SIRvvTwT0qOCBGWIEohdxnu6DpC1BRKQ2RNgsGnO88N5+8FYGor1M4+UT38d/JMrgx8MGkW305ioCmW888NmVuNMheEh19wyFqp9FCQED2DsLxU3pi7A5w4knA5eIy89ULPOrNFUMq5LIBA5OdERrnNS6Yk5/kMmepH2A0tj9pFqBzxdFtThQtYYZ1UnxrotfE+YvU587FW3iXowpHAsaGeoLA3XkakCuZ6jpZhKwOWvslBcBt/6Irs0MPmj5EyaIOb8kAACij8nIfWQkQu/2Ik/AZ0L4lw36RRYNMdel8fMZAwcmK1bfh51dJqhTsf2e4iLa9xHCx7/Mib8EriDwRdYeO0GWSRk4cwTyIY2JjpkidgbDy2BHpiFxp9v/mNf6nJYYVG1Arnv/tK0t3WeILkOHy7tkWtGwFrjiRVQ7B2Hq+iBgda0reZSncK56GhmrMiHwO95QPe6hh3oz3lwcl7MoKGCyLASTeXTKNGhR5fds/6fG25bov8DDOaWXbQyeidJwO4UvLY6ksS3onc= diff --git a/composer.json b/composer.json index 41c53fc..ae59add 100644 --- a/composer.json +++ b/composer.json @@ -19,8 +19,8 @@ } ], "require": { - "php": "^7.2 || ^8.0", - "laravel/framework": "^11.0 || ^10.0 || ^9.0 || >=8.40.0 || ^7.0", + "php": "^8.0", + "laravel/framework": "^11.0 || ^10.0 || ^9.0", "zircote/swagger-php": "^3.2.0 || ^4.0.0", "swagger-api/swagger-ui": "^3.0 || >=4.1.3", "symfony/yaml": "^5.0 || ^6.0 || ^7.0", diff --git a/phpunit-php80.xml b/phpunit-php80.xml new file mode 100644 index 0000000..fd1b3f2 --- /dev/null +++ b/phpunit-php80.xml @@ -0,0 +1,29 @@ + + + + + tests + + + + + src + + + + + + + diff --git a/phpunit.xml b/phpunit.xml index 378379b..07bcfb7 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -24,5 +24,8 @@ src/ + + src/routes.php + diff --git a/src/helpers.php b/src/helpers.php index b574f60..424b3d3 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -14,7 +14,7 @@ */ function swagger_ui_dist_path(string $documentation, $asset = null) { - $allowed_files = [ + $allowedFiles = [ 'favicon-16x16.png', 'favicon-32x32.png', 'oauth2-redirect.html', @@ -37,7 +37,7 @@ function swagger_ui_dist_path(string $documentation, $asset = null) return realpath($path); } - if (! in_array($asset, $allowed_files)) { + if (! in_array($asset, $allowedFiles, true)) { throw new L5SwaggerException(sprintf('(%s) - this L5 Swagger asset is not allowed', $asset)); } diff --git a/tests/ConfigFactoryTest.php b/tests/ConfigFactoryTest.php index c6ded03..20afab6 100644 --- a/tests/ConfigFactoryTest.php +++ b/tests/ConfigFactoryTest.php @@ -2,17 +2,20 @@ namespace Tests; +use L5Swagger\ConfigFactory; use L5Swagger\Exceptions\L5SwaggerException; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\TestDox; /** - * @testdox Configuration factory + * @covers \L5Swagger\ConfigFactory */ +#[TestDox('Configuration factory')] +#[CoversClass(ConfigFactory::class)] class ConfigFactoryTest extends TestCase { - /** - * @test - */ - public function itThrowsExceptionIfDocumentationConfigNotFound(): void + public function testItThrowsExceptionIfDocumentationConfigNotFound(): void { $config = config('l5-swagger'); unset($config['documentations']['default']); @@ -25,16 +28,12 @@ public function itThrowsExceptionIfDocumentationConfigNotFound(): void } /** - * @test - * * @dataProvider configDataProvider * - * @param array $data - * @param array $assert - * * @throws L5SwaggerException */ - public function canMergeConfigurationDeep(array $data, array $assert): void + #[DataProvider('configDataProvider')] + public function testCanMergeConfigurationDeep(array $data, array $assert): void { config(['l5-swagger' => array_merge( $data, @@ -58,72 +57,70 @@ public function canMergeConfigurationDeep(array $data, array $assert): void $this->assertArraySimilar($config, $assert); } - public static function configDataProvider(): array + public static function configDataProvider(): \Iterator { - return [ - [ - [ - 'default' => 'v2', - 'documentations' => [ - 'v2' => [ - 'api' => [ - 'title' => 'Api V2', - ], - 'paths' => [ - 'docs_json' => 'api-v2.json', - ], - 'proxy' => true, + yield 'V1 configuration' => [ + 'data' => [ + 'default' => 'v2', + 'documentations' => [ + 'v2' => [ + 'api' => [ + 'title' => 'Api V2', ], + 'paths' => [ + 'docs_json' => 'api-v2.json', + ], + 'proxy' => true, ], ], - [ - 'api' => [ - 'title' => 'Api V2', - ], - 'routes' => [ - 'api' => 'api/documentation', - 'docs' => 'docs', - ], - 'paths' => [ - 'docs_json' => 'api-v2.json', - 'docs' => 'docs/', - 'docs_yaml' => 'docs.yaml', - ], - 'proxy' => true, + ], + 'assert' => [ + 'api' => [ + 'title' => 'Api V2', + ], + 'routes' => [ + 'api' => 'api/documentation', + 'docs' => 'docs', + ], + 'paths' => [ + 'docs_json' => 'api-v2.json', + 'docs' => 'docs/', + 'docs_yaml' => 'docs.yaml', ], + 'proxy' => true, ], - [ - [ - 'default' => 'v1', - 'documentations' => [ - 'v1' => [ - 'api' => [ - 'title' => 'Api V1', - ], - 'routes' => [ - 'api' => 'api/v1', - ], - 'paths' => [ - 'docs_json' => 'api-v1.json', - ], + ]; + yield 'V2 configuration' => [ + 'data' => [ + 'default' => 'v1', + 'documentations' => [ + 'v1' => [ + 'api' => [ + 'title' => 'Api V1', + ], + 'routes' => [ + 'api' => 'api/v1', + ], + 'paths' => [ + 'docs_json' => 'api-v1.json', ], ], ], - [ - 'api' => [ - 'title' => 'Api V1', - ], - 'routes' => [ - 'api' => 'api/v1', - 'docs' => 'docs', - ], - 'paths' => [ - 'docs_json' => 'api-v1.json', - 'docs' => 'docs/', - 'docs_yaml' => 'docs.yaml', - ], - 'proxy' => false, + ], + 'assert' => [ + 'api' => [ + 'title' => 'Api V1', + ], + 'routes' => [ + 'api' => 'api/v1', + 'docs' => 'docs', ], + 'paths' => [ + 'docs_json' => 'api-v1.json', + 'docs' => 'docs/', + 'docs_yaml' => 'docs.yaml', + ], + 'proxy' => false, ], ]; } @@ -133,13 +130,10 @@ public static function configDataProvider(): array * * Both arrays must have the same indexes with identical values * without respect to key ordering - * - * @param array $expected - * @param array $array */ - protected function assertArraySimilar(array $expected, array $array) + protected function assertArraySimilar(array $expected, array $array): void { - $this->assertTrue(count(array_diff_key($array, $expected)) === 0); + $this->assertSame([], array_diff_key($array, $expected)); foreach ($expected as $key => $value) { if (is_array($value)) { diff --git a/tests/ConsoleTest.php b/tests/ConsoleTest.php index ba8dd7e..579058c 100644 --- a/tests/ConsoleTest.php +++ b/tests/ConsoleTest.php @@ -5,24 +5,27 @@ use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Facades\Artisan; +use L5Swagger\Console\GenerateDocsCommand; use L5Swagger\Exceptions\L5SwaggerException; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\TestDox; /** - * @testdox Console commands + * @covers \L5Swagger\Console\GenerateDocsCommand */ +#[TestDox('Console commands')] +#[CoversClass(GenerateDocsCommand::class)] class ConsoleTest extends TestCase { /** - * @test - * * @dataProvider provideGenerateCommands * - * @param string $artisanCommand - * * @throws L5SwaggerException * @throws FileNotFoundException */ - public function canGenerate(string $artisanCommand): void + #[DataProvider('provideGenerateCommands')] + public function testCanGenerate(string $artisanCommand): void { $fileSystem = new Filesystem(); @@ -38,9 +41,6 @@ public function canGenerate(string $artisanCommand): void $this->assertStringContainsString('L5 Swagger', $fileContent); } - /** - * @return iterable - */ public static function provideGenerateCommands(): iterable { yield 'default' => [ @@ -52,11 +52,9 @@ public static function provideGenerateCommands(): iterable } /** - * @test - * * @throws L5SwaggerException */ - public function canPublish(): void + public function testCanPublish(): void { $fileSystem = new Filesystem(); Artisan::call('vendor:publish', ['--provider' => 'L5Swagger\L5SwaggerServiceProvider']); diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index c60129b..b7066d5 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -4,18 +4,29 @@ use Illuminate\Http\Request; use L5Swagger\Exceptions\L5SwaggerException; +use L5Swagger\Generator; +use L5Swagger\GeneratorFactory; +use L5Swagger\L5SwaggerServiceProvider; use OpenApi\Analysers\TokenAnalyser; use OpenApi\Processors\CleanUnmerged; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\TestDox; use Symfony\Component\Yaml\Parser; use Symfony\Component\Yaml\Yaml; /** - * @testdox Generator + * @covers \L5Swagger\Generator */ +#[TestDox('Generator')] +#[CoversClass(GeneratorFactory::class)] +#[CoversClass(Generator::class)] +#[CoversClass(L5SwaggerServiceProvider::class)] class GeneratorTest extends TestCase { - /** @test **/ - public function itThrowsExceptionIfDocumentationDirIsNotWritable(): void + /** + * @throws L5SwaggerException + */ + public function testItThrowsExceptionIfDocumentationDirIsNotWritable(): void { $this->setAnnotationsPath(); @@ -41,8 +52,10 @@ public function itThrowsExceptionIfDocumentationDirIsNotWritable(): void $this->generator->generateDocs(); } - /** @test **/ - public function itWillCreateDocumentationDirIfItIsWritable(): void + /** + * @throws L5SwaggerException + */ + public function testItWillCreateDocumentationDirIfItIsWritable(): void { $this->setAnnotationsPath(); @@ -72,8 +85,10 @@ public function itWillCreateDocumentationDirIfItIsWritable(): void $this->generator->generateDocs(); } - /** @test **/ - public function itThrowsExceptionIfDocumentationDirWasNotCreated(): void + /** + * @throws L5SwaggerException + */ + public function testItThrowsExceptionIfDocumentationDirWasNotCreated(): void { $this->setAnnotationsPath(); @@ -104,15 +119,17 @@ public function itThrowsExceptionIfDocumentationDirWasNotCreated(): void $this->generator->generateDocs(); } - /** @test */ - public function canGenerateApiJsonFile(): void + /** + * @throws L5SwaggerException + */ + public function testCanGenerateApiJsonFile(): void { $this->setAnnotationsPath(); $this->generator->generateDocs(); - $this->assertTrue(file_exists($this->jsonDocsFile())); - $this->assertTrue(file_exists($this->yamlDocsFile())); + $this->assertFileExists($this->jsonDocsFile()); + $this->assertFileExists($this->yamlDocsFile()); $this->get(route('l5-swagger.default.docs')) ->assertSee('L5 Swagger') @@ -133,8 +150,10 @@ public function canGenerateApiJsonFile(): void ->assertStatus(200); } - /** @test */ - public function canGenerateWithLegacyExcludedDirectories(): void + /** + * @throws L5SwaggerException + */ + public function testCanGenerateWithLegacyExcludedDirectories(): void { $this->setAnnotationsPath(); @@ -152,7 +171,7 @@ public function canGenerateWithLegacyExcludedDirectories(): void $this->generator->generateDocs(); - $this->assertTrue(file_exists($this->jsonDocsFile())); + $this->assertFileExists($this->jsonDocsFile()); $this->get(route('l5-swagger.default.docs')) ->assertSee('L5 Swagger') @@ -163,30 +182,23 @@ public function canGenerateWithLegacyExcludedDirectories(): void ->assertStatus(200); } - /** @test */ - public function canGenerateWithScanOptions(): void + /** + * @throws L5SwaggerException + */ + public function testCanGenerateWithScanOptions(): void { $cfg = config('l5-swagger.documentations.default'); - $cfg['scanOptions']['exclude'] = [ - __DIR__.'/storage/annotations/OpenApi/Clients', - ]; - + $cfg['scanOptions']['exclude'] = [__DIR__.'/storage/annotations/OpenApi/Clients']; $cfg['scanOptions']['pattern'] = 'L5SwaggerAnnotationsExample*.*'; $cfg['scanOptions']['analyser'] = new TokenAnalyser; $cfg['scanOptions']['open_api_spec_version'] = '3.1.0'; - $cfg['scanOptions']['processors'] = [ - new CleanUnmerged, - ]; - $cfg['scanOptions']['default_processors_configuration'] = [ - 'operationId' => ['hash' => false], - ]; + $cfg['scanOptions']['processors'] = [new CleanUnmerged]; + $cfg['scanOptions']['default_processors_configuration'] = ['operationId' => ['hash' => false]]; config(['l5-swagger' => [ 'default' => 'default', - 'documentations' => [ - 'default' => $cfg, - ], + 'documentations' => ['default' => $cfg], 'defaults' => config('l5-swagger.defaults'), ]]); @@ -194,7 +206,7 @@ public function canGenerateWithScanOptions(): void $this->generator->generateDocs(); - $this->assertTrue(file_exists($this->jsonDocsFile())); + $this->assertFileExists($this->jsonDocsFile()); $response = $this->get(route('l5-swagger.default.docs')); @@ -208,8 +220,10 @@ public function canGenerateWithScanOptions(): void ->assertStatus(200); } - /** @test */ - public function canGenerateApiJsonFileWithChangedBaseServer(): void + /** + * @throws L5SwaggerException + */ + public function testCanGenerateApiJsonFileWithChangedBaseServer(): void { $this->setAnnotationsPath(); @@ -225,7 +239,7 @@ public function canGenerateApiJsonFileWithChangedBaseServer(): void $this->generator->generateDocs(); - $this->assertTrue(file_exists($this->jsonDocsFile())); + $this->assertFileExists($this->jsonDocsFile()); $this->get(route('l5-swagger.default.docs')) ->assertSee('https://test-server.url') @@ -242,8 +256,10 @@ public function canGenerateApiJsonFileWithChangedBaseServer(): void ->assertStatus(200); } - /** @test */ - public function canSetProxy(): void + /** + * @throws L5SwaggerException + */ + public function testCanSetProxy(): void { $this->setAnnotationsPath(); @@ -261,17 +277,19 @@ public function canSetProxy(): void $this->get(route('l5-swagger.default.api')) ->assertStatus(200); - $this->assertEquals(Request::getTrustedProxies()[0], $proxy); + $this->assertSame(Request::getTrustedProxies()[0], $proxy); $this->get(route('l5-swagger.default.docs')) ->assertStatus(200); - $this->assertTrue(file_exists($this->jsonDocsFile())); - $this->assertTrue(file_exists($this->yamlDocsFile())); + $this->assertFileExists($this->jsonDocsFile()); + $this->assertFileExists($this->yamlDocsFile()); } - /** @test */ - public function canSetValidatorUrl(): void + /** + * @throws L5SwaggerException + */ + public function testCanSetValidatorUrl(): void { $this->setAnnotationsPath(); @@ -298,12 +316,14 @@ public function canSetValidatorUrl(): void $this->get(route('l5-swagger.default.docs')) ->assertStatus(200); - $this->assertTrue(file_exists($this->jsonDocsFile())); - $this->assertTrue(file_exists($this->yamlDocsFile())); + $this->assertFileExists($this->jsonDocsFile()); + $this->assertFileExists($this->yamlDocsFile()); } - /** @test */ - public function canAppropriateYamlType(): void + /** + * @throws L5SwaggerException + */ + public function testCanAppropriateYamlType(): void { $this->setAnnotationsPath(); diff --git a/tests/HelpersTest.php b/tests/HelpersTest.php index a410040..103a25b 100644 --- a/tests/HelpersTest.php +++ b/tests/HelpersTest.php @@ -3,17 +3,53 @@ namespace Tests; use L5Swagger\Exceptions\L5SwaggerException; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\CoversFunction; +use PHPUnit\Framework\Attributes\TestDox; /** - * @testdox Helpers + * @covers L5SwaggerException */ +#[TestDox('Helpers')] +#[CoversClass(L5SwaggerException::class)] +#[CoversFunction('l5_swagger_asset')] +#[CoversFunction('swagger_ui_dist_path')] class HelpersTest extends TestCase { - /** @test */ - public function assetFunctionThrowsExceptionIfFileDoesNotExists(): void + public function testAssetFunctionReturnsRoute(): void + { + $path = l5_swagger_asset('default', 'swagger-ui.js'); + + $this->assertStringContainsString('http://localhost/docs/asset/swagger-ui.js?v=', $path); + } + + /** + * @throws L5SwaggerException + */ + public function testGeneratesBasePathForAssetsThrowsExceptionIfFileIsNotAllowed(): void { $this->expectException(L5SwaggerException::class); - l5_swagger_asset('default', 'asdasd'); + swagger_ui_dist_path('default', 'foo.bar'); + } + + /** + * @throws L5SwaggerException + */ + public function testGeneratesBasePathForAssets(): void + { + $path = swagger_ui_dist_path('default'); + + $this->assertStringContainsString('swagger-api/swagger-ui/dist', $path); + } + + /** + * @throws L5SwaggerException + */ + public function testGeneratesAssetPathForAssets(): void + { + $path = swagger_ui_dist_path('default', 'swagger-ui.js'); + + $this->assertStringContainsString('swagger-api/swagger-ui/dist/swagger-ui.js', $path); } } diff --git a/tests/RoutesTest.php b/tests/RoutesTest.php index 3ab3b10..4bf5a80 100644 --- a/tests/RoutesTest.php +++ b/tests/RoutesTest.php @@ -2,18 +2,31 @@ namespace Tests; +use Illuminate\Http\Request; use L5Swagger\Exceptions\L5SwaggerException; use L5Swagger\Generator; use L5Swagger\GeneratorFactory; +use L5Swagger\Http\Controllers\SwaggerAssetController; +use L5Swagger\Http\Controllers\SwaggerController; +use L5Swagger\Http\Middleware\Config; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\MockObject\MockObject; /** - * @testdox Routes + * @covers \L5Swagger\Http\Controllers\SwaggerController + * @covers \L5Swagger\Http\Controllers\SwaggerAssetController */ +#[TestDox('Routes')] +#[CoversClass(SwaggerController::class)] +#[CoversClass(SwaggerAssetController::class)] +#[CoversClass(Config::class)] +#[CoversClass(L5SwaggerException::class)] class RoutesTest extends TestCase { - /** @test */ - public function userCantAccessJsonFileIfItIsNotGenerated(): void + public function testUserCantAccessJsonFileIfItIsNotGenerated(): void { $jsonUrl = route('l5-swagger.default.docs'); @@ -21,8 +34,10 @@ public function userCantAccessJsonFileIfItIsNotGenerated(): void $this->assertTrue($response->isNotFound()); } - /** @test */ - public function userCanAccessJsonFileIfItIsGenerated(): void + /** + * @throws L5SwaggerException + */ + public function testUserCanAccessJsonFileIfItIsGenerated(): void { $jsonUrl = route('l5-swagger.default.docs'); config(['l5-swagger' => [ @@ -39,8 +54,10 @@ public function userCanAccessJsonFileIfItIsGenerated(): void ->isOk(); } - /** @test */ - public function userCanAccessAndGenerateCustomJsonFile(): void + /** + * @throws L5SwaggerException + */ + public function testUserCanAccessAndGenerateCustomJsonFile(): void { $customJsonFileName = 'docs.v1.json'; @@ -62,8 +79,10 @@ public function userCanAccessAndGenerateCustomJsonFile(): void ->isOk(); } - /** @test */ - public function userCanAccessAndGenerateYamlFile(): void + /** + * @throws L5SwaggerException + */ + public function testUserCanAccessAndGenerateYamlFile(): void { $customYamlFileName = 'docs.yaml'; @@ -84,8 +103,7 @@ public function userCanAccessAndGenerateYamlFile(): void ->isOk(); } - /** @test */ - public function itCanAccessAndGenerateYamlFile(): void + public function testItCanAccessAndGenerateYamlFile(): void { $customYamlFileName = 'docs.yaml'; @@ -106,8 +124,10 @@ public function itCanAccessAndGenerateYamlFile(): void ->isOk(); } - /** @test */ - public function userCanAccessDocumentationFileWithoutExtensionIfItExists(): void + /** + * @throws L5SwaggerException + */ + public function testUserCanAccessDocumentationFileWithoutExtensionIfItExists(): void { $customYamlFileName = 'docs-file-without-extension'; @@ -128,8 +148,10 @@ public function userCanAccessDocumentationFileWithoutExtensionIfItExists(): void ->isOk(); } - /** @test */ - public function itDoesNotThrowExceptionOnDocsFileWithoutExtension(): void + /** + * @throws L5SwaggerException + */ + public function testItDoesNotThrowExceptionOnDocsFileWithoutExtension(): void { $fileWithoutExtension = 'docs'; @@ -143,11 +165,9 @@ public function itDoesNotThrowExceptionOnDocsFileWithoutExtension(): void } /** - * @test - * * @throws L5SwaggerException */ - public function userCanAccessDocumentationInterface(): void + public function testUserCanAccessDocumentationInterface(): void { $config = $this->configFactory->documentationConfig(); $jsonFile = $config['paths']['docs_json'] ?? 'api-docs.json'; @@ -159,19 +179,49 @@ public function userCanAccessDocumentationInterface(): void } /** - * @test + * @dataProvider provideProxies * * @throws L5SwaggerException */ - public function itCanServeAssets(): void + #[DataProvider('provideProxies')] + public function testUserCanAccessDocumentationInterfaceAndConfigureProxy( + mixed $proxy, + array $expectedProxies + ): void { + config(['l5-swagger' => [ + 'default' => 'default', + 'documentations' => config('l5-swagger.documentations'), + 'defaults' => array_merge(config('l5-swagger.defaults'), ['proxy' => $proxy]), + ]]); + + $config = $this->configFactory->documentationConfig(); + $jsonFile = $config['paths']['docs_json'] ?? 'api-docs.json'; + + $this->get($config['routes']['api']) + ->assertSee(route('l5-swagger.default.docs', $jsonFile)) + ->assertSee(route('l5-swagger.default.oauth2_callback')) + ->isOk(); + + $this->assertSame($expectedProxies, Request::getTrustedProxies()); + } + + public static function provideProxies(): \Generator + { + yield 'proxies array' => ['proxy' => ['foo', 'bar'], 'expectedProxies' => ['foo', 'bar']]; + yield 'proxy as string' => ['proxy' => 'baz', 'expectedProxies' => ['baz']]; + } + + /** + * @throws L5SwaggerException + */ + public function testItCanServeAssets(): void { $this->get(l5_swagger_asset('default', 'swagger-ui.css')) ->assertSee('.swagger-ui') ->isOk(); } - /** @test */ - public function itWillThrowExceptionForIncorrectAsset(): void + public function testItWillThrowExceptionForIncorrectAsset(): void { $this->expectException(L5SwaggerException::class); $this->expectExceptionMessage('(bad-swagger-ui.css) - this L5 Swagger asset is not allowed'); @@ -179,15 +229,13 @@ public function itWillThrowExceptionForIncorrectAsset(): void l5_swagger_asset('default', 'bad-swagger-ui.css'); } - /** @test */ - public function itHandleBadAssetRequest(): void + public function testItHandleBadAssetRequest(): void { $this->get(route('l5-swagger.default.asset', 'file.css')) ->assertNotFound(); } - /** @test */ - public function userCanAccessOauth2Redirect(): void + public function testUserCanAccessOauth2Redirect(): void { $this->get(route('l5-swagger.default.oauth2_callback')) ->assertSee('swaggerUIRedirectOauth2') @@ -195,16 +243,14 @@ public function userCanAccessOauth2Redirect(): void ->isOk(); } - /** @test */ - public function itWillReturn404ForIncorrectJsonFile(): void + public function testItWillReturn404ForIncorrectJsonFile(): void { $jsonUrl = route('l5-swagger.default.docs', 'invalid.json'); $this->get($jsonUrl)->assertNotFound(); } - /** @test */ - public function itWillNotAttemptDocGenerationWhenAlwaysGenerateIsDisabled(): void + public function testItWillNotAttemptDocGenerationWhenAlwaysGenerateIsDisabled(): void { $jsonUrl = route('l5-swagger.default.docs', 'unknown_file.json'); config(['l5-swagger' => [ @@ -219,8 +265,7 @@ public function itWillNotAttemptDocGenerationWhenAlwaysGenerateIsDisabled(): voi $this->get($jsonUrl)->assertNotFound(); } - /** @test */ - public function itWillReturn404WhenDocGenerationFails(): void + public function testItWillReturn404WhenDocGenerationFails(): void { $jsonUrl = route('l5-swagger.default.docs', 'docs'); config(['l5-swagger' => [ @@ -230,19 +275,21 @@ public function itWillReturn404WhenDocGenerationFails(): void ]]); $mockGenerator = $this->mockGenerator(); - $mockGenerator->expects($this->once())->method('generateDocs')->will($this->throwException(new \Exception)); + $mockGenerator->expects($this->once())->method('generateDocs')->willThrowException(new L5SwaggerException()); $this->get($jsonUrl)->assertNotFound(); } /** - * @return MockObject&Generator + * @return Generator&MockObject + * + * @throws Exception */ - private function mockGenerator() + private function mockGenerator(): Generator { $mockGenerator = $this->createMock(Generator::class); $mockGeneratorFactory = $this->createMock(GeneratorFactory::class); - $mockGeneratorFactory->expects($this->any())->method('make')->willReturn($mockGenerator); + $mockGeneratorFactory->method('make')->willReturn($mockGenerator); app()->extend(GeneratorFactory::class, function () use ($mockGeneratorFactory) { return $mockGeneratorFactory; }); diff --git a/tests/SecurityDefinitionsTest.php b/tests/SecurityDefinitionsTest.php index c788a62..b7ffc59 100644 --- a/tests/SecurityDefinitionsTest.php +++ b/tests/SecurityDefinitionsTest.php @@ -4,18 +4,22 @@ use Illuminate\Filesystem\Filesystem; use L5Swagger\Exceptions\L5SwaggerException; +use L5Swagger\SecurityDefinitions; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\TestDox; /** - * @testdox Security definition + * @covers \L5Swagger\SecurityDefinitions */ +#[TestDox('Security definition')] +#[CoversClass(SecurityDefinitions::class)] class SecurityDefinitionsTest extends TestCase { /** - * @test - * * @throws L5SwaggerException */ - public function itWillNotAddEmptySecurityItems(): void + public function testItWillNotAddEmptySecurityItems(): void { $fileSystem = new Filesystem(); @@ -51,16 +55,12 @@ public function itWillNotAddEmptySecurityItems(): void } /** - * @test - * * @dataProvider provideConfigAndSchemes * - * @param array $securitySchemes - * @param array $security - * * @throws L5SwaggerException */ - public function canGenerateApiJsonFileWithSecurityDefinition( + #[DataProvider('provideConfigAndSchemes')] + public function testCanGenerateApiJsonFileWithSecurityDefinition( array $securitySchemes, array $security ): void { @@ -86,7 +86,7 @@ public function canGenerateApiJsonFileWithSecurityDefinition( $this->assertTrue($fileSystem->exists($this->jsonDocsFile())); $this->get(route('l5-swagger.default.docs')) - ->assertSee('new_api_key_securitye') + ->assertSee('new_api_key_security') ->assertSee('oauth2') // From annotations ->assertSee('read:projects') ->assertSee('read:oauth2') // From annotations @@ -95,13 +95,10 @@ public function canGenerateApiJsonFileWithSecurityDefinition( ->isOk(); } - /** - * @return iterable - */ public static function provideConfigAndSchemes(): iterable { $securitySchemes = [ - 'new_api_key_securitye' => [ + 'new_api_key_security' => [ 'type' => 'apiKey', 'name' => 'api_key_name', 'in' => 'query', @@ -109,7 +106,7 @@ public static function provideConfigAndSchemes(): iterable ]; $security = [ - 'new_api_key_securitye' => [ + 'new_api_key_security' => [ 'read:projects', ], ]; diff --git a/tests/TestCase.php b/tests/TestCase.php index 6625405..5a58a6d 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -9,44 +9,41 @@ use L5Swagger\Generator; use L5Swagger\L5SwaggerServiceProvider; use Orchestra\Testbench\TestCase as OrchestraTestCase; +use PHPUnit\Framework\Attributes\Before; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\MockObject\MockObject; use ReflectionObject; class TestCase extends OrchestraTestCase { /** - * @var ConfigFactory + * @var ConfigFactory|MockObject */ - protected $configFactory; + protected ConfigFactory $configFactory; - /** - * @var array - */ - protected $defaultConfig; + protected array $defaultConfig; /** - * @var Generator + * @var Generator|MockObject */ - protected $generator; + protected Generator $generator; /** - * @var MockObject|Filesystem + * @var Filesystem|MockObject */ - protected $fileSystem; + protected Filesystem $fileSystem; /** * @before * - * @return void + * @throws Exception */ + #[Before] public function setUpFileSystem(): void { $this->fileSystem = $this->createMock(Filesystem::class); } - /** - * @return void - */ public function setUp(): void { parent::setUp(); @@ -83,7 +80,7 @@ public function tearDown(): void /** * @param Application $app - * @return array + * @return string[] */ protected function getPackageProviders($app): array { @@ -117,8 +114,6 @@ protected function createYamlDocumentationFile(): void /** * Get path for json docs file. * - * @return string - * * @throws L5SwaggerException */ protected function jsonDocsFile(): string @@ -137,8 +132,6 @@ protected function jsonDocsFile(): string /** * Get path for yaml docs file. * - * @return string - * * @throws L5SwaggerException */ protected function yamlDocsFile(): string @@ -194,9 +187,6 @@ protected function makeGenerator(): void $this->generator = $this->app->make(Generator::class); } - /** - * @return void - */ protected function makeGeneratorWithMockedFileSystem(): void { $this->generator = $this->app->make(Generator::class); @@ -208,10 +198,6 @@ protected function makeGeneratorWithMockedFileSystem(): void $reflectionProperty->setValue($this->generator, $this->fileSystem); } - /** - * @param string $fileName - * @param string $type - */ protected function setCustomDocsFileName(string $fileName, string $type = 'json'): void { $cfg = config('l5-swagger.documentations.default');