From b254870c3bc38616fbd45c8884712a34915ac774 Mon Sep 17 00:00:00 2001 From: Diego Smania Date: Sun, 4 Aug 2024 11:57:59 -0300 Subject: [PATCH] Add new adminlte:remove command (#1299) * [src/Console]: Add new adminlte:remove command * [src/Console]: Fix style CI in new remove command * [tests/Console]: Add tests for the remove command * [tests/Console]: Replace arrow function due to compatibility with old Laravel versions * [tests/Console]: Fix code style in remove command tests * [tests/Console]: Improve remove command tests --- src/AdminLteServiceProvider.php | 4 +- src/Console/AdminLteRemoveCommand.php | 120 ++++++++++++++++ tests/Console/RemoveTest.php | 189 ++++++++++++++++++++++++++ 3 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 src/Console/AdminLteRemoveCommand.php create mode 100644 tests/Console/RemoveTest.php diff --git a/src/AdminLteServiceProvider.php b/src/AdminLteServiceProvider.php index 2aa95a14..2acbb271 100644 --- a/src/AdminLteServiceProvider.php +++ b/src/AdminLteServiceProvider.php @@ -7,6 +7,7 @@ use Illuminate\Support\ServiceProvider as BaseServiceProvider; use JeroenNoten\LaravelAdminLte\Console\AdminLteInstallCommand; use JeroenNoten\LaravelAdminLte\Console\AdminLtePluginCommand; +use JeroenNoten\LaravelAdminLte\Console\AdminLteRemoveCommand; use JeroenNoten\LaravelAdminLte\Console\AdminLteStatusCommand; use JeroenNoten\LaravelAdminLte\Console\AdminLteUpdateCommand; use JeroenNoten\LaravelAdminLte\View\Components\Form; @@ -157,9 +158,10 @@ private function registerCommands() if ($this->app->runningInConsole()) { $this->commands([ AdminLteInstallCommand::class, + AdminLtePluginCommand::class, + AdminLteRemoveCommand::class, AdminLteStatusCommand::class, AdminLteUpdateCommand::class, - AdminLtePluginCommand::class, ]); } } diff --git a/src/Console/AdminLteRemoveCommand.php b/src/Console/AdminLteRemoveCommand.php new file mode 100644 index 00000000..7c4b2b5d --- /dev/null +++ b/src/Console/AdminLteRemoveCommand.php @@ -0,0 +1,120 @@ +pkgResources = [ + 'assets' => new AdminlteAssetsResource(), + 'config' => new ConfigResource(), + 'translations' => new TranslationsResource(), + 'main_views' => new LayoutViewsResource(), + 'auth_views' => new AuthViewsResource(), + 'auth_routes' => new AuthRoutesResource(), + 'components' => new BladeComponentsResource(), + ]; + } + + /** + * Execute the console command. + * + * @return void + */ + public function handle() + { + // Read and verify the resources to be uninstalled. + + foreach ($this->argument('resource') as $res) { + // Check if resource is valid. + + if (! isset($this->pkgResources[$res])) { + $this->comment("The provided resource: {$res} is invalid!"); + + continue; + } + + // Uninstall the resource. + + $this->uninstallPackageResource($res); + } + } + + /** + * Uninstalls a package resource. + * + * @param string $resource The keyword of the resource to uninstall + * @return void + */ + protected function uninstallPackageResource($resource) + { + $removeMsg = 'Do you really want to uninstall the resource: :res?'; + $removeMsg = str_replace(':res', $resource, $removeMsg); + $resource = $this->pkgResources[$resource]; + + // Check if the --interactive option is enabled. + + if ($this->option('interactive') && ! $this->confirm($removeMsg)) { + return; + } + + // Check whether to warn for uninstalling a required resource. + + $requiredWarnMsg = 'This resource is required by the package, '; + $requiredWarnMsg .= 'do you really want to uninstall it?'; + + $shouldWarn = ! $this->option('force') && $resource->required; + + if ($shouldWarn && ! $this->confirm($requiredWarnMsg)) { + return; + } + + // Uninstall the resource. + + $resource->uninstall(); + $this->info('The resource was successfully removed'); + } +} diff --git a/tests/Console/RemoveTest.php b/tests/Console/RemoveTest.php new file mode 100644 index 00000000..8c922a04 --- /dev/null +++ b/tests/Console/RemoveTest.php @@ -0,0 +1,189 @@ +artisan('adminlte:remove dummy') + ->expectsOutput('The provided resource: dummy is invalid!') + ->assertExitCode(0); + } + + public function testRemoveAllResourcesIndividually() + { + // We can't perfom these tests on old Laravel versions. We need support + // for the expect confirmation method. + + if (! $this->canExpectsConfirmation()) { + $this->assertTrue(true); + + return; + } + + // Test remove command over the available resources. + + foreach ($this->getResources() as $name => $res) { + // Ensure the required vendor assets exists, if needed. + + if ($name === 'assets') { + $this->installVendorAssets(); + } + + // Ensure the target resource is installed. + + $res->install(); + + // Remove resource using the artisan command. + + if ($res->required) { + $confirmMsg = 'This resource is required by the package, '; + $confirmMsg .= 'do you really want to uninstall it?'; + + $this->artisan("adminlte:remove {$name}") + ->expectsConfirmation($confirmMsg, 'yes'); + } else { + $this->artisan("adminlte:remove {$name}"); + } + + $this->assertFalse($res->installed()); + } + } + + public function testRemoveAllResourcesAtOnceWithForceFlag() + { + // We can't perfom these tests on old Laravel versions. We need support + // for the expect confirmation method. + + if (! $this->canExpectsConfirmation()) { + $this->assertTrue(true); + + return; + } + + // Install all the available resources and collect their names. + + $resNames = []; + + foreach ($this->getResources() as $name => $res) { + $resNames[] = $name; + + // Ensure the required vendor assets exists, if needed. + + if ($name === 'assets') { + $this->installVendorAssets(); + } + + // Ensure the target resource is installed. + + $res->install(); + } + + // Test remove all resources at once. + + $resNames = implode(' ', $resNames); + $this->artisan("adminlte:remove --force {$resNames}"); + + // Control that all resources were removed. + + foreach ($this->getResources() as $res) { + $this->assertFalse($res->installed()); + } + } + + public function testRemoveOnRequiredResourcesWithoutConfirmation() + { + // We can't perfom these tests on old Laravel versions. We need support + // for the expect confirmation method. + + if (! $this->canExpectsConfirmation()) { + $this->assertTrue(true); + + return; + } + + // Get set of required resources. + + $resources = array_filter( + $this->getResources(), + function ($r) { + return $r->required; + } + ); + + // Test remove command over the required resources, without + // confirming the action. + + foreach ($resources as $name => $res) { + // Ensure the required vendor assets exists, if needed. + + if ($name === 'assets') { + $this->installVendorAssets(); + } + + // Ensure the target resource is installed. + + $res->install(); + + // Remove resource using the artisan command, but don't confirm the + // action. + + $confirmMsg = 'This resource is required by the package, '; + $confirmMsg .= 'do you really want to uninstall it?'; + + $this->artisan("adminlte:remove {$name}") + ->expectsConfirmation($confirmMsg, 'no'); + + // Assert the resource is still installed. + + $this->assertTrue($res->installed()); + + // Clear the installed resource. + + $res->uninstall(); + $this->assertFalse($res->installed()); + } + } + + public function testRemoveInteractiveFlagWithoutConfirmation() + { + // We can't perfom these tests on old Laravel versions. We need support + // for the expect confirmation method. + + if (! $this->canExpectsConfirmation()) { + $this->assertTrue(true); + + return; + } + + // Test remove command over the resources when using --interactive. + + foreach ($this->getResources() as $name => $res) { + $confirmMsg = 'Do you really want to uninstall the resource: :res?'; + $confirmMsg = str_replace(':res', $name, $confirmMsg); + + // Ensure the required vendor assets exists, if needed. + + if ($name === 'assets') { + $this->installVendorAssets(); + } + + // Ensure the target resource is installed. + + $res->install(); + + // Test with --interactive option and respond with NO. + + $this->artisan("adminlte:remove {$name} --interactive") + ->expectsConfirmation($confirmMsg, 'no'); + + // Assert the resource is still installed. + + $this->assertTrue($res->installed()); + + // Clear the installed resource. + + $res->uninstall(); + $this->assertFalse($res->installed()); + } + } +}