diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 3855a08..7963b38 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -8,19 +8,21 @@ on: jobs: phpstan: - name: phpstan runs-on: ubuntu-latest + name: PHPStan Latest steps: - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.1' + php-version: 8.5 coverage: none - - name: Install composer dependencies - uses: ramsey/composer-install@v3 + - name: Install dependencies + env: + XDEBUG_MODE: off + run: composer update --prefer-stable --prefer-dist --no-interaction --no-progress --ansi - name: Run PHPStan - run: ./vendor/bin/phpstan --error-format=github + run: ./vendor/bin/phpstan analyse -c phpstan.neon.dist --error-format=github diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index a9f101b..f6b1b85 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -8,37 +8,76 @@ on: jobs: test: - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest strategy: fail-fast: true matrix: - os: [ubuntu-latest] - php: [8.1, 8.2] - laravel: [10.*, 11.*, 12.*] - stability: [prefer-stable] include: - - laravel: 10.* - testbench: 8.* - php: 8.1 - - laravel: 11.* + - php: 8.2 + laravel: 11.* + filament: 4.* testbench: 9.* - php: 8.2 - - laravel: 12.* + livewire: ^3.0 + pest: ^3.8 + pest_plugin_laravel: ^3.1 + pest_plugin_livewire: ^3.1 + - php: 8.2 + laravel: 12.* + filament: 4.* testbench: 10.* - php: 8.2 + livewire: ^3.0 + pest: ^3.8 + pest_plugin_laravel: ^3.1 + pest_plugin_livewire: ^3.1 + - php: 8.3 + laravel: 12.* + filament: 5.* + testbench: 10.* + livewire: ^4.0 + pest: ^4.0 + pest_plugin_laravel: ^4.0 + pest_plugin_livewire: ^4.0 + - php: 8.4 + laravel: 12.* + filament: 5.* + testbench: 10.* + livewire: ^4.0 + pest: ^4.0 + pest_plugin_laravel: ^4.0 + pest_plugin_livewire: ^4.0 + - php: 8.5 + laravel: 12.* + filament: 5.* + testbench: 10.* + livewire: ^4.0 + pest: ^4.0 + pest_plugin_laravel: ^4.0 + pest_plugin_livewire: ^4.0 - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} + name: P${{ matrix.php }} - L${{ matrix.laravel }} steps: - name: Checkout code uses: actions/checkout@v4 + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: vendor + key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ matrix.laravel }}-${{ matrix.filament }}-${{ matrix.testbench }}-${{ matrix.livewire }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-${{ matrix.php }}-${{ matrix.laravel }}-${{ matrix.filament }}-${{ matrix.testbench }}-${{ matrix.livewire }}- + ${{ runner.os }}-composer- + - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo - coverage: none + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo, pcov + coverage: pcov - name: Setup problem matchers run: | @@ -46,9 +85,35 @@ jobs: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - name: Install dependencies + env: + XDEBUG_MODE: off run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update - composer update --${{ matrix.stability }} --prefer-dist --no-interaction + composer require \ + "laravel/framework:${{ matrix.laravel }}" \ + "orchestra/testbench:${{ matrix.testbench }}" \ + "filament/filament:${{ matrix.filament }}" \ + "livewire/livewire:${{ matrix.livewire }}" \ + "pestphp/pest:${{ matrix.pest }}" \ + "pestphp/pest-plugin-laravel:${{ matrix.pest_plugin_laravel }}" \ + "pestphp/pest-plugin-livewire:${{ matrix.pest_plugin_livewire }}" \ + --no-interaction --no-update --no-progress --ansi + composer update --prefer-stable --prefer-dist --no-interaction --no-progress --ansi - - name: Execute tests - run: vendor/bin/pest + - name: Prepare coverage directory + run: mkdir -p build/logs + + - name: Execute tests with coverage + run: vendor/bin/pest --coverage --coverage-clover build/logs/clover.xml + + - name: Sanitize artifact name + run: | + LARAVEL_SAFE=$(echo "${{ matrix.laravel }}" | tr '*' 'x') + FILAMENT_SAFE=$(echo "${{ matrix.filament }}" | tr '*' 'x') + echo "ARTIFACT_NAME=coverage-${{ matrix.php }}-${LARAVEL_SAFE}-${FILAMENT_SAFE}" >> $GITHUB_ENV + + - name: Upload coverage artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME }} + path: build/logs/clover.xml + if-no-files-found: error diff --git a/.gitignore b/.gitignore index 8271e65..12d978a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ -.DS_Store +**/.DS_Store .idea .phpunit.result.cache +.phpunit.cache .vscode build composer.lock diff --git a/README.md b/README.md index c81d6ae..5756e70 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,12 @@ Add a button to easily clear the cache from your filament admin. #### Compatibility -| Plugin Version | Filament Version | PHP Version | -|----------------|-----------------|-------------| -| [1.x](https://github.com/cms-multi/filament-clear-cache/tree/1.x) | 2.x | \> 8.0 | -| [2.x](https://github.com/cms-multi/filament-clear-cache/tree/2.x) | 3.x | \> 8.1 | +| Plugin Version | Filament Version | PHP Version | +|-------------------------------------------------------------------|------------------|-------------| +| [1.x](https://github.com/cms-multi/filament-clear-cache/tree/1.x) | 2.x | \> 8.0 | +| [2.x](https://github.com/cms-multi/filament-clear-cache/tree/2.x) | 3.x | \> 8.1 | +| [3.x](https://github.com/cms-multi/filament-clear-cache/tree/3.x) | 4.x + 5.x | \> 8.2 | + ## Installation @@ -67,7 +69,7 @@ To increment the button count call Livewire event `clearCacheIncrement`. // Livewire v2 $this->emit('clearCacheIncrement'); -// Livewire v3 +// Livewire v3+ $this->dispatch('clearCacheIncrement')->to(\CmsMulti\FilamentClearCache\Http\Livewire\ClearCache::class); ``` diff --git a/composer.json b/composer.json index 5af8bd3..5b3feea 100644 --- a/composer.json +++ b/composer.json @@ -2,9 +2,9 @@ "name": "cms-multi/filament-clear-cache", "description": "Clear your cache easily from within filament", "keywords": [ - "filament", - "laravel", - "filament-clear-cache" + "filament-clear-cache", + "filamentphp", + "laravel" ], "homepage": "https://github.com/cms-multi/filament-clear-cache", "support": { @@ -20,25 +20,23 @@ } ], "require": { - "php": "^8.1", - "filament/filament": "^3.0", - "filament/notifications": "^3.0", - "spatie/laravel-package-tools": "^1.15.0", - "illuminate/contracts": "^10.0|^11.0|^12.0" + "php": "^8.2", + "filament/filament": "^4.0 || ^5.0", + "filament/notifications": "^4.0 || ^5.0", + "spatie/laravel-package-tools": "^1.15", + "illuminate/contracts": "^11.0 || ^12.0" }, "require-dev": { "laravel/pint": "^1.0", - "nunomaduro/collision": "^7.9", - "nunomaduro/larastan": "^2.0.1", - "orchestra/testbench": "^8.0", - "pestphp/pest": "^2.0", - "pestphp/pest-plugin-arch": "^2.0", - "pestphp/pest-plugin-laravel": "^2.0", - "pestphp/pest-plugin-livewire": "^2.1", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "spatie/laravel-ray": "^1.26" + "larastan/larastan": "^3.0", + "orchestra/testbench": "^10.0", + "pestphp/pest": "^4.0", + "pestphp/pest-plugin-laravel": "^4.0", + "pestphp/pest-plugin-livewire": "^4.0", + "phpstan/phpstan": "^2.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0" }, "autoload": { "psr-4": { @@ -52,14 +50,16 @@ }, "scripts": { "post-autoload-dump": "@php ./vendor/bin/testbench package:discover --ansi", - "analyse": "vendor/bin/phpstan analyse", - "test": "vendor/bin/pest", - "test-coverage": "vendor/bin/pest --coverage", - "format": "vendor/bin/pint" + "analyse": "phpstan analyse", + "lint": "pint", + "test": "pest", + "test:coverage": "pest --coverage", + "test:lint": "pint --test" }, "config": { "sort-packages": true, "allow-plugins": { + "composer/package-versions-deprecated": true, "pestphp/pest-plugin": true, "phpstan/extension-installer": true } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon deleted file mode 100644 index e69de29..0000000 diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 9914a5e..6a9db1d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,12 +1,9 @@ -includes: - - phpstan-baseline.neon - parameters: level: 4 paths: - src + - config tmpDir: build/phpstan checkOctaneCompatibility: true checkModelProperties: true - checkMissingIterableValueType: false diff --git a/resources/views/livewire/clear-cache-button.blade.php b/resources/views/livewire/clear-cache-button.blade.php index 155492c..aa54184 100644 --- a/resources/views/livewire/clear-cache-button.blade.php +++ b/resources/views/livewire/clear-cache-button.blade.php @@ -1,31 +1,39 @@ - + diff --git a/src/FilamentClearCachePlugin.php b/src/FilamentClearCachePlugin.php index bb33671..e7b9f0a 100644 --- a/src/FilamentClearCachePlugin.php +++ b/src/FilamentClearCachePlugin.php @@ -3,6 +3,7 @@ namespace CmsMulti\FilamentClearCache; use CmsMulti\FilamentClearCache\Http\Livewire\ClearCache; +use Composer\InstalledVersions; use Filament\Contracts\Plugin; use Filament\Panel; use Illuminate\Support\Facades\Blade; @@ -14,7 +15,7 @@ class FilamentClearCachePlugin implements Plugin const ID = 'filament-clear-cache'; - const VERSION = '2.0.8'; + const VERSION = '3.0.0'; public static function make(): static { @@ -28,19 +29,35 @@ public function getId(): string public function register(Panel $panel): void { - Livewire::component( - 'filament-clear-cache::clear-cache-button', - config('filament-clear-cache.livewireComponentClass', ClearCache::class) - ); + $component = config('filament-clear-cache.livewireComponentClass', ClearCache::class); + + if (self::isLivewireV3()) { + Livewire::component('filament-clear-cache::clear-cache-button', $component); + } $panel->renderHook( name: 'panels::user-menu.before', - hook: fn (): string => Blade::render('@livewire(\'filament-clear-cache::clear-cache-button\')'), + hook: fn (): string => Blade::render( + '@livewire($component)', + ['component' => $component] + ), ); } public function boot(Panel $panel): void { - // + if (! self::isLivewireV3()) { + Livewire::addNamespace( + namespace: 'filament-clear-cache', + viewPath: __DIR__ . '/../resources/views/livewire', + ); + } + } + + private static function isLivewireV3(): bool + { + $version = InstalledVersions::getVersion('livewire/livewire'); + + return version_compare($version, '4.0.0', '<'); } } diff --git a/tests/ExampleTest.php b/tests/Integration/ClearCacheTest.php similarity index 71% rename from tests/ExampleTest.php rename to tests/Integration/ClearCacheTest.php index 1037663..ac667b8 100644 --- a/tests/ExampleTest.php +++ b/tests/Integration/ClearCacheTest.php @@ -1,6 +1,7 @@ throws(Exception::class); it('can clear cache with auth', function () { - $this->actingAs($this->adminUser); + $this->actingAs(User::create([ + 'name' => 'John', + 'email' => 'test@test.com', + ])); livewire(ClearCache::class) ->call('clear') diff --git a/tests/Integration/CommandTest.php b/tests/Integration/CommandTest.php new file mode 100644 index 0000000..d46350d --- /dev/null +++ b/tests/Integration/CommandTest.php @@ -0,0 +1,55 @@ +set('filament-clear-cache.default_commands', [ + 'config:clear', + 'cache:clear', + ]); + + $exitCode = Artisan::call(FilamentClearCacheCommand::class); + + expect($exitCode)->toBe(0); +}); + +it('runs custom string commands added via facade', function () { + FilamentClearCache::addCommand('route:clear'); + + $exitCode = Artisan::call(FilamentClearCacheCommand::class); + + expect($exitCode)->toBe(0); +}); + +it('runs custom array command with parameters', function () { + FilamentClearCache::addCommand('config:cache', ['--no-ansi' => true]); + + $exitCode = Artisan::call(FilamentClearCacheCommand::class); + + expect($exitCode)->toBe(0); +}); + +it('runs custom closure command', function () { + $ran = false; + FilamentClearCache::addCommand(function () use (&$ran) { + $ran = true; + }); + + $exitCode = Artisan::call(FilamentClearCacheCommand::class); + + expect($exitCode)->toBe(0); + expect($ran)->toBeTrue(); +}); + +it('resets changes_count cache key when configured', function () { + $key = 'filament_clear_cache_changes'; + config()->set('filament-clear-cache.changes_count', $key); + Cache::put($key, 5); + + Artisan::call(FilamentClearCacheCommand::class); + + expect(Cache::get($key))->toBe(0); +}); diff --git a/tests/TestCase.php b/tests/TestCase.php index 23ce2a6..553ce84 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,8 +2,6 @@ namespace CmsMulti\FilamentClearCache\Tests; -use BladeUI\Heroicons\BladeHeroiconsServiceProvider; -use BladeUI\Icons\BladeIconsServiceProvider; use CmsMulti\FilamentClearCache\FilamentClearCacheServiceProvider; use CmsMulti\FilamentClearCache\Tests\Models\User; use CmsMulti\FilamentClearCache\Tests\Provider\AdminPanelProvider; @@ -16,36 +14,23 @@ class TestCase extends Orchestra { - protected User $adminUser; - protected function setUp(): void { parent::setUp(); $this->setUpDatabase($this->app); - - $this->adminUser = User::create([ - 'name' => 'John', - 'email' => 'test@test.com', - ]); - - $this->actingAs($this->adminUser); } protected function getPackageProviders($app) { - $packageProviders = [ - BladeHeroiconsServiceProvider::class, - BladeIconsServiceProvider::class, - LivewireServiceProvider::class, + return [ FilamentServiceProvider::class, NotificationsServiceProvider::class, SupportServiceProvider::class, FilamentClearCacheServiceProvider::class, + LivewireServiceProvider::class, AdminPanelProvider::class, ]; - - return $packageProviders; } /** @@ -63,6 +48,9 @@ protected function setUpDatabase($app) $table->string('name'); }); + // Cache array + $app['cache']->set('cache.default', 'array'); + // self::$migration->up(); } } diff --git a/tests/Unit/FacadeTest.php b/tests/Unit/FacadeTest.php new file mode 100644 index 0000000..89f1bd1 --- /dev/null +++ b/tests/Unit/FacadeTest.php @@ -0,0 +1,16 @@ + true]); + + $commands = FilamentClearCache::getCommands(); + + expect($commands) + ->toHaveCount(2) + ->toContain('view:clear'); + expect($commands[1]) + ->toBe(['config:cache', ['--force' => true]]); +}); diff --git a/tests/Unit/FilamentClearCacheManagerTest.php b/tests/Unit/FilamentClearCacheManagerTest.php new file mode 100644 index 0000000..fd83599 --- /dev/null +++ b/tests/Unit/FilamentClearCacheManagerTest.php @@ -0,0 +1,36 @@ +addCommand('cache:clear'); + + expect($manager->getCommands()) + ->toHaveCount(1) + ->toContain('cache:clear'); +}); + +it('adds array command with params', function () { + $manager = new FilamentClearCacheManager; + $manager->addCommand('config:cache', ['--force' => true]); + + expect($manager->getCommands()[0]) + ->toBe(['config:cache', ['--force' => true]]); +}); + +it('adds closure command', function () { + $manager = new FilamentClearCacheManager; + $ran = false; + $manager->addCommand(function () use (&$ran) { + $ran = true; + }); + + $commands = $manager->getCommands(); + expect($commands)->toHaveCount(1); + // Invoke the closure to ensure it's callable + $closure = $commands[0]; + expect(is_callable($closure))->toBeTrue(); + $closure(); + expect($ran)->toBeTrue(); +});