From 40e07dcda968fbb5d26f7c3aca6e08416976127f Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 22 Jul 2024 23:01:41 +1000 Subject: [PATCH] Switch to github testing from travisci (#49) * Switch to github testing * Also remove styleci * use correct name for matrix versions * Adds composer commands * Create laravel 10 stub * Fix import * Fixes internal request closures Fixes warning about abstract test class (just for neatness) * Fixes auth test * Fixes routetest for adapter args * Fix for phpunit10 * Fix regression for morph event * Fix overriding original content --- .github/workflows/ci.yml | 44 ++++ .gitignore | 1 + .styleci.yml | 8 - .travis.yml | 37 ---- composer.json | 10 +- src/Http/Response.php | 35 ++-- src/Provider/DingoServiceProvider.php | 10 + src/Provider/LaravelServiceProvider.php | 2 +- tests/ChecksLaravelVersionTrait.php | 5 +- tests/DispatcherTest.php | 5 +- tests/Exception/HandlerTest.php | 2 +- tests/Http/Middleware/AuthTest.php | 2 +- tests/Http/ResponseTest.php | 2 +- ...erTest.php => BaseAdapterTestAbstract.php} | 2 +- ...aravelTest.php => LaravelTestAbstract.php} | 2 +- .../{LumenTest.php => LumenTestAbstract.php} | 2 +- tests/Routing/RouteTest.php | 2 +- ...{RouterTest.php => RouterTestAbstract.php} | 2 +- ...rTest.php => UrlGeneratorTestAbstract.php} | 2 +- tests/Stubs/Application10Stub.php | 189 ++++++++++++++++++ tests/Stubs/RoutingAdapterStub.php | 11 + 21 files changed, 303 insertions(+), 72 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .styleci.yml delete mode 100644 .travis.yml rename tests/Routing/Adapter/{BaseAdapterTest.php => BaseAdapterTestAbstract.php} (99%) rename tests/Routing/Adapter/{LaravelTest.php => LaravelTestAbstract.php} (87%) rename tests/Routing/Adapter/{LumenTest.php => LumenTestAbstract.php} (96%) rename tests/Routing/{RouterTest.php => RouterTestAbstract.php} (99%) rename tests/Routing/{UrlGeneratorTest.php => UrlGeneratorTestAbstract.php} (98%) create mode 100644 tests/Stubs/Application10Stub.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..59a49f5a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,44 @@ +name: CI Tests + +on: + pull_request: + push: + branches: + - master + - v* + +jobs: + tests: + runs-on: ubuntu-22.04 + + strategy: + fail-fast: false + matrix: + stability: [prefer-stable] + #versions: [ { php: 8.1, laravel: 10 }, { php: 8.2, laravel: 10 }, { php: 8.3, laravel: 10 }, { php: 8.2, laravel: 11 }, { php: 8.3, laravel: 11 } ] + versions: [ { php: 8.1, laravel: 10 }, { php: 8.2, laravel: 10 }, { php: 8.3, laravel: 10 } ] + + name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + # Docs: https://github.com/shivammathur/setup-php + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.versions.php }} + extensions: dom, curl, libxml, mbstring, zip + ini-values: error_reporting=E_ALL + tools: composer:v2 + # todo: Add + coverage: none + + - name: Install dependencies + run: | + composer require "illuminate/contracts=^${{ matrix.versions.laravel }}" --no-update + composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader + + - name: Run phpunit tests + run: composer test diff --git a/.gitignore b/.gitignore index 08548b28..927f9df7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ vendor .php_cs .phpunit.result.cache .phpunit.result.cache/ +test-results diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index 97e05dcc..00000000 --- a/.styleci.yml +++ /dev/null @@ -1,8 +0,0 @@ -preset: laravel - -disabled: - - alpha_ordered_imports - - laravel_phpdoc_alignment - -enabled: - - unalign_double_arrow diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e2bb65b4..00000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -# Test any changes here to see the impact - https://config.travis-ci.com/explore -dist: bionic -language: php - -php: - - 8.0 - - 8.1.0 - -env: - global: - - setup=basic - - xdebug=false - jobs: - - LARAVEL_VERSION=8.* - - LARAVEL_VERSION=9.* - -cache: - directories: - - $HOME/.composer/cache - -before_install: - - if [[ $xdebug = 'true' ]] ; then phpenv config-rm xdebug.ini; fi - - composer self-update --2 - -install: - - if [[ $setup = 'basic' ]]; then travis_retry composer install --prefer-dist --no-interaction --no-suggest; fi - - if [[ $setup = 'stable' ]]; then travis_retry composer update --prefer-dist --no-interaction --no-suggest --prefer-stable; fi - - if [[ $setup = 'lowest' ]]; then travis_retry composer update --prefer-dist --no-interaction --no-suggest --prefer-stable --prefer-lowest; fi - -before_script: - - travis_retry composer install --prefer-source --no-interaction - - if [ "$LARAVEL_VERSION" != "" ]; then composer require --dev "illuminate/routing:${LARAVEL_VERSION}" --no-update; fi; - - if [ "$LARAVEL_VERSION" != "" ]; then composer require --dev "illuminate/support:${LARAVEL_VERSION}" --no-update; fi; - - composer update - -script: - - vendor/bin/phpunit diff --git a/composer.json b/composer.json index bb394968..0188d64b 100644 --- a/composer.json +++ b/composer.json @@ -68,5 +68,13 @@ "sort-packages": true }, "minimum-stability": "dev", - "prefer-stable": true + "prefer-stable": true, + "scripts": { + "test": [ + "vendor/bin/phpunit" + ], + "lint": [ + "vendor/bin/phpcs" + ] + } } diff --git a/src/Http/Response.php b/src/Http/Response.php index 01c37dfd..24cb56cd 100644 --- a/src/Http/Response.php +++ b/src/Http/Response.php @@ -34,6 +34,13 @@ class Response extends IlluminateResponse */ protected $binding; + /** + * Intermedia content that we are working on. The result content should be a string (symfony) + * ) + * @var mixed Content with which we are working + */ + protected $workingContent; + /** * Array of registered formatters. * @@ -125,12 +132,12 @@ public static function makeFromJson(JsonResponse $json) */ public function morph($format = 'json') { - $content = $this->getOriginalContent() ?? ''; + $this->workingContent = $this->getOriginalContent() ?? ''; $this->fireMorphingEvent(); - if (isset(static::$transformer) && static::$transformer->transformableResponse($content)) { - $content = static::$transformer->transform($content); + if (isset(static::$transformer) && static::$transformer->transformableResponse($this->workingContent)) { + $this->workingContent = static::$transformer->transform($this->workingContent); } $formatter = static::getFormatter($format); @@ -147,21 +154,21 @@ public function morph($format = 'json') $this->fireMorphedEvent(); - if ($content instanceof EloquentModel) { - $content = $formatter->formatEloquentModel($content); - } elseif ($content instanceof EloquentCollection) { - $content = $formatter->formatEloquentCollection($content); - } elseif (is_array($content) || $content instanceof ArrayObject || $content instanceof Arrayable) { - $content = $formatter->formatArray($content); - } elseif ($content instanceof stdClass) { - $content = $formatter->formatArray((array) $content); + if ($this->workingContent instanceof EloquentModel) { + $this->workingContent = $formatter->formatEloquentModel($this->workingContent); + } elseif ($this->workingContent instanceof EloquentCollection) { + $this->workingContent = $formatter->formatEloquentCollection($this->workingContent); + } elseif (is_array($this->workingContent) || $this->workingContent instanceof ArrayObject || $this->workingContent instanceof Arrayable) { + $this->workingContent = $formatter->formatArray($this->workingContent); + } elseif ($this->workingContent instanceof stdClass) { + $this->workingContent = $formatter->formatArray((array) $this->workingContent); } else { if (! empty($defaultContentType)) { $this->headers->set('Content-Type', $defaultContentType); } } - $this->content = $content; + $this->content = $this->workingContent; return $this; } @@ -177,7 +184,7 @@ protected function fireMorphedEvent() return; } - static::$events->dispatch(new ResponseWasMorphed($this, $this->content)); + static::$events->dispatch(new ResponseWasMorphed($this, $this->workingContent)); } /** @@ -191,7 +198,7 @@ protected function fireMorphingEvent() return; } - static::$events->dispatch(new ResponseIsMorphing($this, $this->content)); + static::$events->dispatch(new ResponseIsMorphing($this, $this->workingContent)); } /** diff --git a/src/Provider/DingoServiceProvider.php b/src/Provider/DingoServiceProvider.php index 42518d8c..7800f040 100644 --- a/src/Provider/DingoServiceProvider.php +++ b/src/Provider/DingoServiceProvider.php @@ -2,6 +2,8 @@ namespace Dingo\Api\Provider; +use Illuminate\Routing\CallableDispatcher; +use Illuminate\Routing\Contracts\CallableDispatcher as CallableDispatcherContract; use RuntimeException; use Dingo\Api\Auth\Auth; use Dingo\Api\Dispatcher; @@ -55,6 +57,7 @@ public function register() $this->registerExceptionHandler(); $this->registerDispatcher(); + $this->registerCallableDispatcher(); $this->registerAuth(); @@ -145,6 +148,13 @@ public function registerDispatcher() }); } + public function registerCallableDispatcher() + { + $this->app->singleton(CallableDispatcherContract::class, function ($app) { + return new CallableDispatcher($app); + }); + } + /** * Register the auth. * diff --git a/src/Provider/LaravelServiceProvider.php b/src/Provider/LaravelServiceProvider.php index 8b4808d4..b368e209 100644 --- a/src/Provider/LaravelServiceProvider.php +++ b/src/Provider/LaravelServiceProvider.php @@ -9,7 +9,7 @@ use Illuminate\Contracts\Http\Kernel; use Dingo\Api\Event\RequestWasMatched; use Dingo\Api\Http\Middleware\Request; -use Illuminate\Foundation\Application; +use Illuminate\Contracts\Foundation\Application; use Dingo\Api\Http\Middleware\RateLimit; use Illuminate\Routing\ControllerDispatcher; use Dingo\Api\Http\Middleware\PrepareController; diff --git a/tests/ChecksLaravelVersionTrait.php b/tests/ChecksLaravelVersionTrait.php index 99048f17..1e5b68b1 100644 --- a/tests/ChecksLaravelVersionTrait.php +++ b/tests/ChecksLaravelVersionTrait.php @@ -2,6 +2,7 @@ namespace Dingo\Api\Tests; +use Dingo\Api\Tests\Stubs\Application10Stub; use Dingo\Api\Tests\Stubs\Application9Stub; use Dingo\Api\Tests\Stubs\ApplicationStub; use Dingo\Api\Tests\Stubs\Application8Stub; @@ -55,7 +56,9 @@ private function getApplicationStub() $version = str_replace('v', '', $version); // Return the version stub for the right version - if (version_compare($version, '9.0.0', '>=')) { + if (version_compare($version, '10.0.0', '>=')) { + return new Application10Stub; + } else if (version_compare($version, '9.0.0', '>=')) { return new Application9Stub; } elseif (version_compare($version, '8.0.0', '>=')) { return new Application8Stub; diff --git a/tests/DispatcherTest.php b/tests/DispatcherTest.php index a44e4cd5..cbc0f268 100644 --- a/tests/DispatcherTest.php +++ b/tests/DispatcherTest.php @@ -21,6 +21,8 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Routing\CallableDispatcher; +use Illuminate\Routing\Contracts\CallableDispatcher as CallableDispatcherContract; use Illuminate\Support\Facades\Request as RequestFacade; use Mockery as m; use Symfony\Component\HttpKernel\Exception\GoneHttpException; @@ -67,7 +69,7 @@ public function setUp(): void $this->transformerFactory = new TransformerFactory($this->container, new TransformerStub); - $this->adapter = new RoutingAdapterStub; + $this->adapter = new RoutingAdapterStub($this->container); $this->exception = m::mock(Handler::class); $this->router = new Router($this->adapter, $this->exception, $this->container, null, null); @@ -75,6 +77,7 @@ public function setUp(): void $this->dispatcher = new Dispatcher($this->container, new Filesystem, $this->router, $this->auth); app()->instance(\Illuminate\Routing\Router::class, $this->adapter); + $this->container->singleton(CallableDispatcherContract::class, CallableDispatcher::class); $this->dispatcher->setSubtype('api'); $this->dispatcher->setStandardsTree('vnd'); diff --git a/tests/Exception/HandlerTest.php b/tests/Exception/HandlerTest.php index a8accc78..f4794011 100644 --- a/tests/Exception/HandlerTest.php +++ b/tests/Exception/HandlerTest.php @@ -162,7 +162,7 @@ public function testExceptionTraceIncludedInResponse() $object = json_decode($response->getContent()); - $this->assertObjectHasAttribute('debug', $object); + $this->assertObjectHasProperty('debug', $object); } public function testHttpExceptionsWithNoMessageUseStatusCodeMessage() diff --git a/tests/Http/Middleware/AuthTest.php b/tests/Http/Middleware/AuthTest.php index f328fa43..a8e1919a 100644 --- a/tests/Http/Middleware/AuthTest.php +++ b/tests/Http/Middleware/AuthTest.php @@ -40,7 +40,7 @@ class AuthTest extends BaseTestCase public function setUp(): void { $this->container = new Container; - $this->adapter = new RoutingAdapterStub; + $this->adapter = new RoutingAdapterStub($this->container); $this->router = m::mock(Router::class); $this->auth = m::mock(Auth::class); $this->middleware = new AuthMiddleware($this->router, $this->auth); diff --git a/tests/Http/ResponseTest.php b/tests/Http/ResponseTest.php index 11e9ce72..8cb562fe 100644 --- a/tests/Http/ResponseTest.php +++ b/tests/Http/ResponseTest.php @@ -68,7 +68,7 @@ public function testBuildingWithCustomStatusCodeAndHeaders() public function testChangingContentWithEvents() { $this->events->listen(ResponseWasMorphed::class, function ($event) { - $event->content['foo'] = 'bam!'; + $event->content = '{"foo":"bam!"}'; }); Response::addFormatter('json', new Json); diff --git a/tests/Routing/Adapter/BaseAdapterTest.php b/tests/Routing/Adapter/BaseAdapterTestAbstract.php similarity index 99% rename from tests/Routing/Adapter/BaseAdapterTest.php rename to tests/Routing/Adapter/BaseAdapterTestAbstract.php index 8a9d911f..9475aa6d 100644 --- a/tests/Routing/Adapter/BaseAdapterTest.php +++ b/tests/Routing/Adapter/BaseAdapterTestAbstract.php @@ -13,7 +13,7 @@ use Laravel\Lumen\Application; use Mockery as m; -abstract class BaseAdapterTest extends BaseTestCase +abstract class BaseAdapterTestAbstract extends BaseTestCase { /** * @var Container|Application diff --git a/tests/Routing/Adapter/LaravelTest.php b/tests/Routing/Adapter/LaravelTestAbstract.php similarity index 87% rename from tests/Routing/Adapter/LaravelTest.php rename to tests/Routing/Adapter/LaravelTestAbstract.php index 07e97fdd..fe046f55 100644 --- a/tests/Routing/Adapter/LaravelTest.php +++ b/tests/Routing/Adapter/LaravelTestAbstract.php @@ -7,7 +7,7 @@ use Illuminate\Events\Dispatcher; use Illuminate\Routing\Router; -class LaravelTest extends BaseAdapterTest +class LaravelTestAbstract extends BaseAdapterTestAbstract { public function getAdapterInstance() { diff --git a/tests/Routing/Adapter/LumenTest.php b/tests/Routing/Adapter/LumenTestAbstract.php similarity index 96% rename from tests/Routing/Adapter/LumenTest.php rename to tests/Routing/Adapter/LumenTestAbstract.php index cc412248..c9ad6163 100644 --- a/tests/Routing/Adapter/LumenTest.php +++ b/tests/Routing/Adapter/LumenTestAbstract.php @@ -9,7 +9,7 @@ use Illuminate\Http\Request; use Laravel\Lumen\Application; -class LumenTest extends BaseAdapterTest +class LumenTestAbstract extends BaseAdapterTestAbstract { public function getAdapterInstance() { diff --git a/tests/Routing/RouteTest.php b/tests/Routing/RouteTest.php index a4cfd508..a3c73bfe 100644 --- a/tests/Routing/RouteTest.php +++ b/tests/Routing/RouteTest.php @@ -25,8 +25,8 @@ class RouteTest extends BaseTestCase public function setUp(): void { - $this->adapter = new RoutingAdapterStub; $this->container = new Container; + $this->adapter = new RoutingAdapterStub($this->container); } public function testCreatingNewRoute() diff --git a/tests/Routing/RouterTest.php b/tests/Routing/RouterTestAbstract.php similarity index 99% rename from tests/Routing/RouterTest.php rename to tests/Routing/RouterTestAbstract.php index c186251e..26ebf3b5 100644 --- a/tests/Routing/RouterTest.php +++ b/tests/Routing/RouterTestAbstract.php @@ -13,7 +13,7 @@ use Mockery as m; use Symfony\Component\HttpKernel\Exception\HttpException; -class RouterTest extends Adapter\BaseAdapterTest +class RouterTestAbstract extends Adapter\BaseAdapterTestAbstract { public function getAdapterInstance() { diff --git a/tests/Routing/UrlGeneratorTest.php b/tests/Routing/UrlGeneratorTestAbstract.php similarity index 98% rename from tests/Routing/UrlGeneratorTest.php rename to tests/Routing/UrlGeneratorTestAbstract.php index df66f2e8..0da82b87 100644 --- a/tests/Routing/UrlGeneratorTest.php +++ b/tests/Routing/UrlGeneratorTestAbstract.php @@ -8,7 +8,7 @@ use Dingo\Api\Tests\Stubs\RoutingControllerStub; use Illuminate\Container\Container; -class UrlGeneratorTest extends Adapter\BaseAdapterTest +class UrlGeneratorTestAbstract extends Adapter\BaseAdapterTestAbstract { public function getAdapterInstance() { diff --git a/tests/Stubs/Application10Stub.php b/tests/Stubs/Application10Stub.php new file mode 100644 index 00000000..ad539a6c --- /dev/null +++ b/tests/Stubs/Application10Stub.php @@ -0,0 +1,189 @@ +container = $container; + } + public function dispatch(Request $request, $version) { $routes = $this->routes[$version]; @@ -75,6 +85,7 @@ public function addRoute(array $methods, array $versions, $uri, $action) $route = new IlluminateRoute($methods, $uri, $action); $this->addWhereClausesToRoute($route); + $route->setContainer($this->container); foreach ($versions as $version) { $this->routes[$version]->add($route);