From 7fa4283abcb815ad18ae5811019a6c57e0de68d5 Mon Sep 17 00:00:00 2001 From: Shalvah Date: Sat, 18 Jan 2025 22:40:53 +0100 Subject: [PATCH] Drop Dingo --- .github/workflows/run-tests.yml | 9 - .gitignore | 1 - README.md | 2 +- composer.dingo.json | 98 ------ composer.json | 11 +- composer.lowest.json | 11 +- config/scribe.php | 3 - phpstan.neon | 2 - src/Commands/GenerateDocumentation.php | 2 +- src/Config/Routes.php | 2 - src/Config/Serializer.php | 1 - src/Extracting/FindsFormRequestForMethod.php | 7 +- .../Strategies/GetFromFormRequestBase.php | 14 +- .../Strategies/Responses/ResponseCalls.php | 53 +-- .../GroupedEndpointsFromApp.php | 2 +- src/Matching/RouteMatcher.php | 38 +-- src/Matching/RouteMatcherInterface.php | 3 +- src/Tools/DocumentationConfig.php | 20 +- tests/BaseLaravelTest.php | 3 - .../GenerateDocumentation/BehavioursTest.php | 23 -- .../Responses/ResponseCallsTest.php | 119 ------- tests/Unit/RouteMatcherDingoTest.php | 318 ------------------ 22 files changed, 32 insertions(+), 710 deletions(-) delete mode 100644 composer.dingo.json delete mode 100644 tests/Unit/RouteMatcherDingoTest.php diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 936d4915..69fb501e 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -19,7 +19,6 @@ jobs: - highest include: - {php: '8.1', deps: lowest} - - {php: '8.1', deps: dingo} name: Tests (PHP ${{ matrix.php }} - ${{ matrix.deps }}) @@ -36,10 +35,6 @@ jobs: if: ${{ matrix.deps == 'highest' }} run: composer update - - name: Install dependencies (Dingo) - if: ${{ matrix.deps == 'dingo' }} - run: COMPOSER=composer.dingo.json composer update --prefer-stable - - name: Install dependencies (lowest) if: ${{ matrix.deps == 'lowest' }} run: COMPOSER=composer.lowest.json composer update --prefer-stable @@ -52,7 +47,3 @@ jobs: - name: Execute tests (Lowest) run: COMPOSER=composer.lowest.json composer test-ci if: ${{ matrix.deps == 'lowest' }} - - - name: Execute tests (Dingo) - run: COMPOSER=composer.dingo.json composer test-ci - if: ${{ matrix.deps == 'dingo' }} diff --git a/.gitignore b/.gitignore index 18395254..7e491069 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .DS_Store composer.lock -composer.dingo.lock .php_cs.cache /vendor/ public/ diff --git a/README.md b/README.md index eb63d029..6bb50c1f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ > [v4 is out now](https://scribe.knuckles.wtf/blog/laravel-v4)! Featuring subgroups, easier sorting, and an automated upgrade command. -Scribe helps you generate API documentation for humans from your Laravel/Lumen/[Dingo](https://github.com/dingo/api) codebase. See a live example at [demo.scribe.knuckles.wtf](https://demo.scribe.knuckles.wtf). +Scribe helps you generate API documentation for humans from your Laravel/Lumen codebase. See a live example at [demo.scribe.knuckles.wtf](https://demo.scribe.knuckles.wtf). ## Features - Useful output: diff --git a/composer.dingo.json b/composer.dingo.json deleted file mode 100644 index 0c743344..00000000 --- a/composer.dingo.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "name": "knuckleswtf/scribe", - "license": "MIT", - "description": "Generate API documentation for humans from your Laravel codebase.✍", - "keywords": [ - "API", - "documentation", - "laravel", - "dingo" - ], - "homepage": "http://github.com/knuckleswtf/scribe", - "authors": [ - { - "name": "Shalvah" - } - ], - "require": { - "php": ">=8.0", - "ext-fileinfo": "*", - "ext-json": "*", - "ext-pdo": "*", - "dingo/api": "^2.3|^3.0", - "erusev/parsedown": "1.7.4", - "fakerphp/faker": "^1.9.1", - "illuminate/console": "^8.0|^9.0", - "illuminate/routing": "^8.0|^9.0", - "illuminate/support": "^8.0|^9.0", - "league/flysystem": "^1.1.4|^2.1.1|^3.0", - "mpociot/reflection-docblock": "^1.0.1", - "nikic/php-parser": "^5.0", - "nunomaduro/collision": "^5.10|^6.0|^7.0|^8.0", - "ramsey/uuid": "^4.2.2", - "shalvah/clara": "^3.1.0", - "shalvah/upgrader": ">=0.6.0", - "spatie/data-transfer-object": "^2.6|^3.0", - "symfony/var-exporter": "^5.4|^6.0|^7.0", - "symfony/yaml": "^5.4|^6.0|^7.0" - }, - "require-dev": { - "brianium/paratest": "^6.0", - "dms/phpunit-arraysubset-asserts": "^0.2.0", - "laravel/legacy-factories": "^1.3.0", - "laravel/lumen-framework": "^8.0|^9.0", - "league/fractal": "^0.19.0", - "nikic/fast-route": "^1.3", - "orchestra/testbench": "^6.0|^7.0", - "pestphp/pest": "^1.21", - "phpstan/phpstan": "^1.0", - "phpunit/phpunit": "^9.0|^10.0", - "symfony/css-selector": "^5.4|^6.0", - "symfony/dom-crawler": "^5.4|^6.0" - }, - "suggest": { - "league/fractal": "Required for transformers support" - }, - "autoload": { - "psr-4": { - "Knuckles\\Scribe\\": "src/", - "Knuckles\\Camel\\": "camel/" - } - }, - "autoload-dev": { - "psr-4": { - "Knuckles\\Scribe\\Tests\\": "tests/" - } - }, - "scripts": { - "lint": "phpstan analyse -c ./phpstan.neon src camel --memory-limit 1G", - "test": "phpunit --stop-on-failure --group dingo", - "test-ci": "phpunit --group dingo", - "test-parallel": "paratest -p16 --stop-on-failure --group dingo tests", - "test-parallel-ci": "paratest -p16 --group dingo tests" - }, - "extra": { - "laravel": { - "providers": [ - "Knuckles\\Scribe\\ScribeServiceProvider" - ] - } - }, - "config": { - "preferred-install": "dist", - "sort-packages": true, - "process-timeout": 600, - "allow-plugins": { - "pestphp/pest-plugin": true - } - }, - "replace": { - "mpociot/laravel-apidoc-generator": "*" - }, - "funding": [ - { - "type": "patreon", - "url": "https://patreon.com/shalvah" - } - ] -} diff --git a/composer.json b/composer.json index 28be4671..8593a7f8 100644 --- a/composer.json +++ b/composer.json @@ -5,8 +5,7 @@ "keywords": [ "API", "documentation", - "laravel", - "dingo" + "laravel" ], "homepage": "http://github.com/knuckleswtf/scribe", "authors": [ @@ -62,10 +61,10 @@ }, "scripts": { "lint": "phpstan analyse -c ./phpstan.neon src camel --memory-limit 1G", - "test": "pest --stop-on-failure --exclude-group dingo --colors", - "test-ci": "pest --exclude-group dingo --coverage --min=80", - "test-parallel": "paratest -p16 --stop-on-failure --exclude-group dingo", - "test-parallel-ci": "paratest -p16 --exclude-group dingo" + "test": "pest --stop-on-failure --colors", + "test-ci": "pest --coverage --min=80", + "test-parallel": "paratest -p16 --stop-on-failure", + "test-parallel-ci": "paratest -p16" }, "extra": { "laravel": { diff --git a/composer.lowest.json b/composer.lowest.json index d6b7b56f..12ffd85c 100644 --- a/composer.lowest.json +++ b/composer.lowest.json @@ -5,8 +5,7 @@ "keywords": [ "API", "documentation", - "laravel", - "dingo" + "laravel" ], "homepage": "http://github.com/knuckleswtf/scribe", "authors": [ @@ -63,10 +62,10 @@ }, "scripts": { "lint": "phpstan analyse -c ./phpstan.neon src camel --memory-limit 1G", - "test": "phpunit --stop-on-failure --exclude-group dingo", - "test-ci": "pest --exclude-group dingo --coverage --min=80", - "test-parallel": "paratest -p16 --stop-on-failure --exclude-group dingo", - "test-parallel-ci": "paratest -p16 --exclude-group dingo" + "test": "phpunit --stop-on-failure", + "test-ci": "pest --coverage --min=80", + "test-parallel": "paratest -p16 --stop-on-failure", + "test-parallel-ci": "paratest -p16" }, "extra": { "laravel": { diff --git a/config/scribe.php b/config/scribe.php index b2e0c036..1c404377 100644 --- a/config/scribe.php +++ b/config/scribe.php @@ -22,9 +22,6 @@ // Match only routes whose domains match this pattern (use * as a wildcard to match any characters). Example: 'api.*'. 'domains' => ['*'], - - // [Dingo router only] Match only routes registered under this version. Wildcards are NOT supported. - 'versions' => ['v1'], ], // Include these routes even if they did not match the rules above. diff --git a/phpstan.neon b/phpstan.neon index a4b8265a..2939c97d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,9 +3,7 @@ parameters: reportUnmatchedIgnoredErrors: true inferPrivatePropertyTypeFromConstructor: true ignoreErrors: - - '#Call to an undefined method Illuminate\\Routing\\Route::versions\(\).#' - '#Call to an undefined method ReflectionType::getName\(\).#' - - '#.+Dingo.+#' - '#Call to an undefined method Illuminate\\Contracts\\Filesystem\\Filesystem::path\(\)#' - '#Call to an undefined method Illuminate\\Contracts\\Foundation\\Application::forgetInstance\(\)#' - '#Access to an undefined property Illuminate\\Support\\HigherOrderCollectionProxy#' diff --git a/src/Commands/GenerateDocumentation.php b/src/Commands/GenerateDocumentation.php index ab48547b..75e9ac43 100644 --- a/src/Commands/GenerateDocumentation.php +++ b/src/Commands/GenerateDocumentation.php @@ -28,7 +28,7 @@ class GenerateDocumentation extends Command {--scribe-dir= : Specify the directory where Scribe stores its intermediate output and cache. Defaults to `.`} "; - protected $description = 'Generate API documentation from your Laravel/Dingo routes.'; + protected $description = 'Generate API documentation from your Laravel routes.'; protected DocumentationConfig $docConfig; diff --git a/src/Config/Routes.php b/src/Config/Routes.php index b839b118..7d8ea2d9 100644 --- a/src/Config/Routes.php +++ b/src/Config/Routes.php @@ -7,7 +7,6 @@ class Routes public static function match( array $prefixes = ['api/*'], array $domains = ['*'], - array $dingoVersions = ['v1'], array $alwaysInclude = [], array $alwaysExclude = [], ): static @@ -18,7 +17,6 @@ public static function match( public function __construct( public array $prefixes = [], public array $domains = [], - public array $dingoVersions = [], public array $alwaysInclude = [], public array $alwaysExclude = [] ) diff --git a/src/Config/Serializer.php b/src/Config/Serializer.php index 0b1a74fc..35432f06 100644 --- a/src/Config/Serializer.php +++ b/src/Config/Serializer.php @@ -51,7 +51,6 @@ protected static function generateRoutesConfig(Routes $routesConfig): array 'match' => [ 'prefixes' => $routesConfig->prefixes, 'domains' => $routesConfig->domains, - 'versions' => $routesConfig->dingoVersions, ], 'include' => $routesConfig->alwaysInclude, 'exclude' => $routesConfig->alwaysExclude, diff --git a/src/Extracting/FindsFormRequestForMethod.php b/src/Extracting/FindsFormRequestForMethod.php index cfc8477a..43235025 100644 --- a/src/Extracting/FindsFormRequestForMethod.php +++ b/src/Extracting/FindsFormRequestForMethod.php @@ -2,8 +2,7 @@ namespace Knuckles\Scribe\Extracting; -use Illuminate\Foundation\Http\FormRequest as LaravelFormRequest; -use Dingo\Api\Http\FormRequest as DingoFormRequest; +use Illuminate\Foundation\Http\FormRequest; use ReflectionClass; use ReflectionException; use ReflectionFunctionAbstract; @@ -27,9 +26,7 @@ protected function getFormRequestReflectionClass(ReflectionFunctionAbstract $met continue; } - if ( - (class_exists(LaravelFormRequest::class) && $argumentClass->isSubclassOf(LaravelFormRequest::class)) - || (class_exists(DingoFormRequest::class) && $argumentClass->isSubclassOf(DingoFormRequest::class))) { + if ($argumentClass->isSubclassOf(FormRequest::class)) { return $argumentClass; } } diff --git a/src/Extracting/Strategies/GetFromFormRequestBase.php b/src/Extracting/Strategies/GetFromFormRequestBase.php index b1f68d0a..bd00cc85 100644 --- a/src/Extracting/Strategies/GetFromFormRequestBase.php +++ b/src/Extracting/Strategies/GetFromFormRequestBase.php @@ -4,8 +4,7 @@ use Illuminate\Routing\Route; use Knuckles\Camel\Extraction\ExtractedEndpointData; -use Dingo\Api\Http\FormRequest as DingoFormRequest; -use Illuminate\Foundation\Http\FormRequest as LaravelFormRequest; +use Illuminate\Foundation\Http\FormRequest; use Knuckles\Scribe\Extracting\FindsFormRequestForMethod; use Knuckles\Scribe\Extracting\ParsesValidationRules; use Knuckles\Scribe\Tools\ConsoleOutputUtils as c; @@ -43,7 +42,7 @@ public function getParametersFromFormRequest(ReflectionFunctionAbstract $method, $formRequest = new $className; } // Set the route properly so it works for users who have code that checks for the route. - /** @var LaravelFormRequest|DingoFormRequest $formRequest */ + /** @var FormRequest $formRequest */ $formRequest->setRouteResolver(function () use ($formRequest, $route) { // Also need to bind the request to the route in case their code tries to inspect current request return $route->bind($formRequest); @@ -59,11 +58,9 @@ public function getParametersFromFormRequest(ReflectionFunctionAbstract $method, } /** - * @param LaravelFormRequest|DingoFormRequest $formRequest - * * @return mixed */ - protected function getRouteValidationRules($formRequest) + protected function getRouteValidationRules(FormRequest $formRequest) { if (method_exists($formRequest, 'validator')) { $validationFactory = app(ValidationFactory::class); @@ -77,10 +74,7 @@ protected function getRouteValidationRules($formRequest) return []; } - /** - * @param LaravelFormRequest|DingoFormRequest $formRequest - */ - protected function getCustomParameterData($formRequest) + protected function getCustomParameterData(FormRequest $formRequest) { if (method_exists($formRequest, $this->customParameterDataMethodName)) { return call_user_func_array([$formRequest, $this->customParameterDataMethodName], []); diff --git a/src/Extracting/Strategies/Responses/ResponseCalls.php b/src/Extracting/Strategies/Responses/ResponseCalls.php index fdd640f7..39c14a0b 100644 --- a/src/Extracting/Strategies/Responses/ResponseCalls.php +++ b/src/Extracting/Strategies/Responses/ResponseCalls.php @@ -2,8 +2,6 @@ namespace Knuckles\Scribe\Extracting\Strategies\Responses; -use Dingo\Api\Dispatcher; -use Dingo\Api\Routing\Route as DingoRoute; use Exception; use Illuminate\Contracts\Http\Kernel; use Illuminate\Http\Request; @@ -205,47 +203,6 @@ private function finish() $this->rollbackLaravelConfigChanges(); } - /** - * @param Request $request - * - * @return \Illuminate\Http\JsonResponse|mixed - */ - public function callDingoRoute(Request $request, Route $route) - { - /** @var \Dingo\Api\Dispatcher $dispatcher */ - $dispatcher = app(\Dingo\Api\Dispatcher::class); - - /** @var DingoRoute $route */ - $dispatcher->version($route->versions()[0]); - foreach ($request->headers as $header => $value) { - $dispatcher->header($header, $value); - } - - // set domain and body parameters - $dispatcher->on($request->header('SERVER_NAME')) - ->with($request->request->all()); - - // set URL and query parameters - $uri = $request->getRequestUri(); - $query = $request->getQueryString(); - if (!empty($query)) { - $uri .= "?$query"; - } - - $response = call_user_func_array( - [$dispatcher, strtolower($request->method())], - [$uri] - ); - - // the response from the Dingo dispatcher is the 'raw' response from the controller, - // so we have to ensure it's JSON first - if (!$response instanceof Response) { - $response = response()->json($response); - } - - return $response; - } - public function getMethods(Route $route): array { return array_diff($route->methods(), ['HEAD']); @@ -287,18 +244,12 @@ private function addBodyParameters(Request $request, array $body): void * * @param Route $route * - * @return \Illuminate\Http\JsonResponse|mixed|\Symfony\Component\HttpFoundation\Response + * @return \Symfony\Component\HttpFoundation\Response * @throws Exception */ protected function makeApiCall(Request $request, Route $route) { - if ($this->config->get('router') == 'dingo') { - $response = $this->callDingoRoute($request, $route); - } else { - $response = $this->callLaravelOrLumenRoute($request); - } - - return $response; + return $this->callLaravelOrLumenRoute($request); } protected function callLaravelOrLumenRoute(Request $request): \Symfony\Component\HttpFoundation\Response diff --git a/src/GroupedEndpoints/GroupedEndpointsFromApp.php b/src/GroupedEndpoints/GroupedEndpointsFromApp.php index da388c8a..49669122 100644 --- a/src/GroupedEndpoints/GroupedEndpointsFromApp.php +++ b/src/GroupedEndpoints/GroupedEndpointsFromApp.php @@ -68,7 +68,7 @@ protected function extractEndpointsInfoAndWriteToDisk(RouteMatcherInterface $rou $cachedEndpoints = Camel::loadEndpointsToFlatPrimitivesArray(static::$cacheDir); } - $routes = $routeMatcher->getRoutes($this->docConfig->get('routes', []), $this->docConfig->get('router')); + $routes = $routeMatcher->getRoutes($this->docConfig->get('routes', [])); $endpoints = $this->extractEndpointsInfoFromLaravelApp($routes, $cachedEndpoints, $latestEndpointsData); $groupedEndpoints = collect($endpoints)->groupBy('metadata.groupName')->map(function (Collection $endpointsInGroup) { diff --git a/src/Matching/RouteMatcher.php b/src/Matching/RouteMatcher.php index d6d0f6a6..dd2fbb05 100644 --- a/src/Matching/RouteMatcher.php +++ b/src/Matching/RouteMatcher.php @@ -2,7 +2,6 @@ namespace Knuckles\Scribe\Matching; -use Dingo\Api\Routing\RouteCollection; use Illuminate\Routing\Route; use Illuminate\Support\Facades\Route as RouteFacade; use Illuminate\Support\Str; @@ -10,16 +9,14 @@ class RouteMatcher implements RouteMatcherInterface { - public function getRoutes(array $routeRules = [], string $router = 'laravel'): array + public function getRoutes(array $routeRules = []): array { - $usingDingoRouter = strtolower($router) == 'dingo'; - - return $this->getRoutesToBeDocumented($routeRules, $usingDingoRouter); + return $this->getRoutesToBeDocumented($routeRules); } - private function getRoutesToBeDocumented(array $routeRules, bool $usingDingoRouter = false): array + private function getRoutesToBeDocumented(array $routeRules): array { - $allRoutes = $this->getAllRoutes($usingDingoRouter); + $allRoutes = $this->getAllRoutes(); $matchedRoutes = []; @@ -35,7 +32,7 @@ private function getRoutesToBeDocumented(array $routeRules, bool $usingDingoRout continue; } - if ($this->shouldIncludeRoute($route, $routeRule, $includes, $usingDingoRouter)) { + if ($this->shouldIncludeRoute($route, $routeRule, $includes)) { $matchedRoutes[] = new MatchedRoute($route, $routeRule['apply'] ?? []); } } @@ -44,38 +41,21 @@ private function getRoutesToBeDocumented(array $routeRules, bool $usingDingoRout return $matchedRoutes; } - private function getAllRoutes(bool $usingDingoRouter) + private function getAllRoutes() { - if (! $usingDingoRouter) { - return RouteFacade::getRoutes(); - } - - /** @var \Dingo\Api\Routing\Router $router */ - $router = app(\Dingo\Api\Routing\Router::class); - $allRouteCollections = $router->getRoutes(); - - return collect($allRouteCollections) - ->flatMap(function (RouteCollection $collection) { - return $collection->getRoutes(); - })->toArray(); + return RouteFacade::getRoutes(); } - private function shouldIncludeRoute(Route $route, array $routeRule, array $mustIncludes, bool $usingDingoRouter): bool + private function shouldIncludeRoute(Route $route, array $routeRule, array $mustIncludes): bool { if (RoutePatternMatcher::matches($route, $mustIncludes)) { return true; } - $matchesVersion = true; - if ($usingDingoRouter) { - $matchesVersion = !empty(array_intersect($route->versions(), $routeRule['match']['versions'] ?? [])); - } - $domainsToMatch = $routeRule['match']['domains'] ?? []; $pathsToMatch = $routeRule['match']['prefixes'] ?? []; - return Str::is($domainsToMatch, $route->getDomain()) && Str::is($pathsToMatch, $route->uri()) - && $matchesVersion; + return Str::is($domainsToMatch, $route->getDomain()) && Str::is($pathsToMatch, $route->uri()); } private function shouldExcludeRoute(Route $route, array $routeRule): bool diff --git a/src/Matching/RouteMatcherInterface.php b/src/Matching/RouteMatcherInterface.php index 1b666587..043de1f2 100644 --- a/src/Matching/RouteMatcherInterface.php +++ b/src/Matching/RouteMatcherInterface.php @@ -8,9 +8,8 @@ interface RouteMatcherInterface * Resolve matched routes that should be documented. * * @param array $routeRules Route rules defined under the "routes" section in config - * @param string $router * * @return MatchedRoute[] */ - public function getRoutes(array $routeRules = [], string $router = 'laravel'): array; + public function getRoutes(array $routeRules = []): array; } diff --git a/src/Tools/DocumentationConfig.php b/src/Tools/DocumentationConfig.php index baf7cd25..0ddc1dc0 100644 --- a/src/Tools/DocumentationConfig.php +++ b/src/Tools/DocumentationConfig.php @@ -11,7 +11,7 @@ class DocumentationConfig public function __construct(array $config = []) { - $config['router'] = $this->getRouter($config); + $config['router'] = 'laravel'; $this->data = $config; } @@ -29,24 +29,6 @@ public function get(string $key, $default = null) return data_get($this->data, $key, $default); } - private function getRouter(array $config): string - { - if ($router = data_get($config, 'router', null)) { - if (!in_array($router, ['dingo', 'laravel'])) { - throw new \InvalidArgumentException("Unknown `router` config value: $router"); - } - return $router; - } - - if (class_exists(\Dingo\Api\Routing\Router::class)) { - c::info('Detected Dingo API router'); - return 'dingo'; - } - - return 'laravel'; - - } - public function outputIsStatic(): bool { return !$this->outputRoutedThroughLaravel(); diff --git a/tests/BaseLaravelTest.php b/tests/BaseLaravelTest.php index 256c65a1..e622305f 100644 --- a/tests/BaseLaravelTest.php +++ b/tests/BaseLaravelTest.php @@ -38,9 +38,6 @@ protected function getPackageProviders($app) $providers = [ ScribeServiceProvider::class, ]; - if (class_exists(\Dingo\Api\Provider\LaravelServiceProvider::class)) { - $providers[] = \Dingo\Api\Provider\LaravelServiceProvider::class; - } return $providers; } diff --git a/tests/GenerateDocumentation/BehavioursTest.php b/tests/GenerateDocumentation/BehavioursTest.php index c655f8f1..e804d269 100644 --- a/tests/GenerateDocumentation/BehavioursTest.php +++ b/tests/GenerateDocumentation/BehavioursTest.php @@ -80,29 +80,6 @@ public function can_process_closure_routes() $this->generateAndExpectConsoleOutput('Processed route: [GET] api/closure'); } - /** - * @group dingo - * @test - */ - public function can_process_routes_on_dingo() - { - $api = app(\Dingo\Api\Routing\Router::class); - $api->version('v1', function ($api) { - $api->get('/closure', function () { - return 'foo'; - }); - $api->get('/test', [TestController::class, 'withEndpointDescription']); - }); - - $this->setConfig(['routes.0.match.prefixes' => ['*']]); - $this->setConfig(['routes.0.match.versions' => ['v1']]); - - $this->generateAndExpectConsoleOutput( - 'Processed route: [GET] closure', - 'Processed route: [GET] test' - ); - } - /** @test */ public function calls_afterGenerating_hook() { diff --git a/tests/Strategies/Responses/ResponseCallsTest.php b/tests/Strategies/Responses/ResponseCallsTest.php index 55c0c527..2a9ec877 100644 --- a/tests/Strategies/Responses/ResponseCallsTest.php +++ b/tests/Strategies/Responses/ResponseCallsTest.php @@ -2,7 +2,6 @@ namespace Knuckles\Scribe\Tests\Strategies\Responses; -use Dingo\Api\Routing\Router; use Illuminate\Routing\Route; use Illuminate\Support\Facades\Route as RouteFacade; use Knuckles\Camel\Extraction\ExtractedEndpointData; @@ -189,105 +188,6 @@ public function calls_beforeResponseCall_hook() Scribe::beforeResponseCall(fn() => null); } - /** - * @test - * @group dingo - */ - public function can_call_route_and_fetch_response_with_dingo() - { - $route = $this->registerDingoRoute('post', '/shouldFetchRouteResponse', 'shouldFetchRouteResponse'); - - $rules = [ - 'response_calls' => [ - 'methods' => ['*'], - ], - ]; - - $strategy = new ResponseCalls(new DocumentationConfig()); - $results = $strategy(ExtractedEndpointData::fromRoute($route), $this->convertRules($rules)); - - $this->assertEquals(200, $results[0]['status']); - $this->assertArraySubset([ - 'id' => 4, - 'name' => 'banana', - 'color' => 'red', - 'weight' => '1 kg', - 'delicious' => true, - ], json_decode($results[0]['content'], true)); - } - - /** - * @test - * @group dingo - */ - public function uses_configured_settings_when_calling_route_with_dingo() - { - $route = $this->registerDingoRoute('post', '/echo/{id}', 'echoesRequestValues'); - - $rules = [ - 'response_calls' => [ - 'methods' => ['*'], - 'queryParams' => [ - 'queryParam' => 'queryValue', - ], - 'bodyParams' => [ - 'bodyParam' => 'bodyValue', - ], - ], - ]; - - $endpointData = ExtractedEndpointData::fromRoute($route, [ - 'headers' => [ - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', - 'header' => 'headerValue', - ], - ]); - $strategy = new ResponseCalls(new DocumentationConfig()); - $results = $strategy($endpointData, $this->convertRules($rules)); - - $this->assertEquals(200, $results[0]['status']); - - $responseContent = json_decode($results[0]['content'], true); - $this->assertEquals('queryValue', $responseContent['queryParam']); - $this->assertEquals('bodyValue', $responseContent['bodyParam']); - $this->assertEquals('headerValue', $responseContent['header']); - } - - /** - * @test - * @group dingo - */ - public function can_override_application_config_during_response_call_with_dingo() - { - $route = $this->registerDingoRoute('post', '/echoesConfig', 'echoesConfig'); - - $rules = [ - 'response_calls' => [ - 'methods' => ['*'], - ], - ]; - - $strategy = new ResponseCalls(new DocumentationConfig()); - $results = $strategy(ExtractedEndpointData::fromRoute($route), $this->convertRules($rules)); - $originalValue = json_decode($results[0]['content'], true)['app.env']; - - $now = time(); - $rules = [ - 'response_calls' => [ - 'methods' => ['*'], - 'config' => [ - 'app.env' => $now, - ], - ], - ]; - - $results = $strategy(ExtractedEndpointData::fromRoute($route), $this->convertRules($rules)); - $newValue = json_decode($results[0]['content'], true)['app.env']; - $this->assertEquals($now, $newValue); - $this->assertNotEquals($originalValue, $newValue); - } - /** @test */ public function does_not_make_response_call_if_success_response_already_gotten() { @@ -313,25 +213,6 @@ public function does_not_make_response_call_if_success_response_already_gotten() $this->assertNull($results); } - public function registerDingoRoute(string $httpMethod, string $path, string $controllerMethod) - { - $desiredRoute = null; - /** @var Router $api */ - $api = app(Router::class); - $api->version('v1', function (Router $api) use ($controllerMethod, $path, $httpMethod, &$desiredRoute) { - $desiredRoute = $api->$httpMethod($path, [TestController::class, $controllerMethod]); - }); - $routes = app(\Dingo\Api\Routing\Router::class)->getRoutes('v1'); - - /* - * Doing this bc we want an instance of Dingo\Api\Routing\Route, not Illuminate\Routing\Route, which the method above returns - */ - return collect($routes) - ->first(function (Route $route) use ($desiredRoute) { - return $route->uri() === $desiredRoute->uri(); - }); - } - protected function convertRules(array $rules): mixed { return Extractor::transformOldRouteRulesIntoNewSettings('responses', $rules, ResponseCalls::class); diff --git a/tests/Unit/RouteMatcherDingoTest.php b/tests/Unit/RouteMatcherDingoTest.php deleted file mode 100644 index ab2a79c5..00000000 --- a/tests/Unit/RouteMatcherDingoTest.php +++ /dev/null @@ -1,318 +0,0 @@ -registerDingoRoutes(); - $routeRules[0]['match']['versions'] = ['v1']; - $routeRules[0]['match']['prefixes'] = ['*']; - - $routeRules[0]['match']['domains'] = ['*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(12, $routes); - - $routeRules[0]['match']['domains'] = ['domain1.*', 'domain2.*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(12, $routes); - - $routeRules[0]['match']['domains'] = ['domain1.*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(6, $routes); - foreach ($routes as $route) { - $this->assertStringContainsString('domain1', $route['route']->getDomain()); - } - - $routeRules[0]['match']['domains'] = ['domain2.*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(6, $routes); - foreach ($routes as $route) { - $this->assertStringContainsString('domain2', $route['route']->getDomain()); - } - } - - /** @test */ - public function respects_prefixes_rule_for_dingo_router() - { - $this->registerDingoRoutes(); - $routeRules[0]['match']['versions'] = ['v1']; - $routeRules[0]['match']['domains'] = ['*']; - - $routeRules[0]['match']['prefixes'] = ['*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(12, $routes); - - $routeRules[0]['match']['prefixes'] = ['prefix1/*', 'prefix2/*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(8, $routes); - - $routeRules[0]['match']['prefixes'] = ['prefix1/*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(4, $routes); - foreach ($routes as $route) { - $this->assertTrue(Str::is('prefix1/*', $route['route']->uri())); - } - - $routeRules[0]['match']['prefixes'] = ['prefix2/*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(4, $routes); - foreach ($routes as $route) { - $this->assertTrue(Str::is('prefix2/*', $route['route']->uri())); - } - } - - /** @test */ - public function respects_versions_rule_for_dingo_router() - { - $this->registerDingoRoutes(); - - $routeRules[0]['match']['versions'] = ['v2']; - $routeRules[0]['match']['domains'] = ['*']; - $routeRules[0]['match']['prefixes'] = ['*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(6, $routes); - foreach ($routes as $route) { - $this->assertNotEmpty(array_intersect($route['route']->versions(), ['v2'])); - } - - $routeRules[0]['match']['versions'] = ['v1', 'v2']; - $routeRules[0]['match']['domains'] = ['*']; - $routeRules[0]['match']['prefixes'] = ['*']; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(18, $routes); - } - - /** @test */ - public function includes_route_if_listed_explicitly_for_dingo_router() - { - $this->registerDingoRoutes(); - - $mustInclude = 'v2.domain2'; - $routeRules = [ - [ - 'match' => [ - 'domains' => ['domain1.*'], - 'prefixes' => ['prefix1/*'], - 'versions' => ['v1'], - ], - 'include' => [$mustInclude], - ], - ]; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $oddRuleOut = collect($routes)->filter(function ($route) use ($mustInclude) { - return $route['route']->getName() === $mustInclude; - }); - $this->assertCount(1, $oddRuleOut); - } - - /** @test */ - public function includes_route_if_match_for_an_include_pattern_for_dingo_router() - { - $this->registerDingoRoutes(); - - $mustInclude = ['v2.domain1', 'v2.domain2']; - $includePattern = 'v2.domain*'; - $routeRules = [ - [ - 'match' => [ - 'domains' => ['domain1.*'], - 'prefixes' => ['prefix1/*'], - 'versions' => ['v1'], - ], - 'include' => [$includePattern], - ], - ]; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $oddRuleOut = collect($routes)->filter(function ($route) use ($mustInclude) { - return in_array($route['route']->getName(), $mustInclude); - }); - $this->assertCount(count($mustInclude), $oddRuleOut); - } - - /** @test */ - public function excludes_route_if_listed_explicitly_for_dingo_router() - { - $this->registerDingoRoutes(); - - $mustNotInclude = 'v2.domain2'; - $routeRules = [ - [ - 'match' => [ - 'domains' => ['domain2.*'], - 'prefixes' => ['*'], - 'versions' => ['v2'], - ], - 'exclude' => [$mustNotInclude], - ], - ]; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $oddRuleOut = collect($routes)->filter(function ($route) use ($mustNotInclude) { - return $route['route']->getName() === $mustNotInclude; - }); - $this->assertCount(0, $oddRuleOut); - } - - /** @test */ - public function excludes_route_if_match_for_an_exclude_patter_for_dingo_router() - { - $this->registerDingoRoutes(); - - $mustNotInclude = ['v2.prefix1.domain2', 'v2.prefix2.domain2']; - $excludePattern = 'v2.*.domain2'; - $routeRules = [ - [ - 'match' => [ - 'domains' => ['domain2.*'], - 'prefixes' => ['*'], - 'versions' => ['v2'], - ], - 'exclude' => [$excludePattern], - ], - ]; - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $oddRuleOut = collect($routes)->filter(function ($route) use ($mustNotInclude) { - return in_array($route['route']->getName(), $mustNotInclude); - }); - $this->assertCount(0, $oddRuleOut); - } - - /** @test */ - public function merges_routes_from_different_rule_groups_for_dingo_router() - { - $this->registerDingoRoutes(); - $routeRules = [ - [ - 'match' => [ - 'domains' => ['*'], - 'prefixes' => ['*'], - 'versions' => ['v1'], - ], - ], - [ - 'match' => [ - 'domains' => ['*'], - 'prefixes' => ['*'], - 'versions' => ['v2'], - ], - ], - ]; - - $matcher = new RouteMatcher(); - $routes = $matcher->getRoutes($routeRules, 'dingo'); - $this->assertCount(18, $routes); - - $routes = collect($routes); - $firstRuleGroup = $routes->filter(function ($route) { - return ! empty(array_intersect($route['route']->versions(), ['v1'])); - }); - $this->assertCount(12, $firstRuleGroup); - - $secondRuleGroup = $routes->filter(function ($route) { - return ! empty(array_intersect($route['route']->versions(), ['v2'])); - }); - $this->assertCount(6, $secondRuleGroup); - } - - private function registerDingoRoutes() - { - $api = app('api.router'); - $api->version('v1', function (Router $api) { - $api->group(['domain' => 'domain1.app.test'], function (Router $api) { - $api->post('/domain1-1', function () { - return 'hi'; - })->name('v1.domain1-1'); - $api->get('domain1-2', function () { - return 'hi'; - })->name('v1.domain1-2'); - $api->get('/prefix1/domain1-1', function () { - return 'hi'; - })->name('v1.prefix1.domain1-1'); - $api->get('prefix1/domain1-2', function () { - return 'hi'; - })->name('v1.prefix1.domain1-2'); - $api->get('/prefix2/domain1-1', function () { - return 'hi'; - })->name('v1.prefix2.domain1-1'); - $api->get('prefix2/domain1-2', function () { - return 'hi'; - })->name('v1.prefix2.domain1-2'); - }); - $api->group(['domain' => 'domain2.app.test'], function (Router $api) { - $api->post('/domain2-1', function () { - return 'hi'; - })->name('v1.domain2-1'); - $api->get('domain2-2', function () { - return 'hi'; - })->name('v1.domain2-2'); - $api->get('/prefix1/domain2-1', function () { - return 'hi'; - })->name('v1.prefix1.domain2-1'); - $api->get('prefix1/domain2-2', function () { - return 'hi'; - })->name('v1.prefix1.domain2-2'); - $api->get('/prefix2/domain2-1', function () { - return 'hi'; - })->name('v1.prefix2.domain2-1'); - $api->get('prefix2/domain2-2', function () { - return 'hi'; - })->name('v1.prefix2.domain2-2'); - }); - }); - $api->version('v2', function (Router $api) { - $api->group(['domain' => 'domain1.app.test'], function (Router $api) { - $api->post('/domain1', function () { - return 'hi'; - })->name('v2.domain1'); - $api->get('/prefix1/domain1', function () { - return 'hi'; - })->name('v2.prefix1.domain1'); - $api->get('/prefix2/domain1', function () { - return 'hi'; - })->name('v2.prefix2.domain1'); - }); - $api->group(['domain' => 'domain2.app.test'], function (Router $api) { - $api->post('/domain2', function () { - return 'hi'; - })->name('v2.domain2'); - $api->get('/prefix1/domain2', function () { - return 'hi'; - })->name('v2.prefix1.domain2'); - $api->get('/prefix2/domain2', function () { - return 'hi'; - })->name('v2.prefix2.domain2'); - }); - }); - } -}