diff --git a/src/Commands/Run.php b/src/Commands/Run.php index 075f9116..a24fb9c7 100644 --- a/src/Commands/Run.php +++ b/src/Commands/Run.php @@ -5,7 +5,9 @@ declare(strict_types=1); namespace Stancl\Tenancy\Commands; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Artisan; +use Illuminate\Contracts\Console\Kernel; +use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Output\ConsoleOutput; class Run extends Command { @@ -29,12 +31,27 @@ class Run extends Command */ public function handle() { - tenancy()->runForMultiple($this->option('tenants'), function ($tenant) { + $argvInput = $this->ArgvInput(); + tenancy()->runForMultiple($this->option('tenants'), function ($tenant) use ($argvInput) { $this->line("Tenant: {$tenant->getTenantKey()}"); - Artisan::call($this->argument('commandname')); - $this->comment('Command output:'); - $this->info(Artisan::output()); + $this->getLaravel() + ->make(Kernel::class) + ->handle($argvInput, new ConsoleOutput); }); } + + /** + * Get command as ArgvInput instance. + */ + protected function ArgvInput(): ArgvInput + { + // Convert string command to array + $subCommand = explode(' ', $this->argument('commandname')); + + // Add "artisan" as first parameter because ArgvInput expects "artisan" as first parameter and later removes it + array_unshift($subCommand, 'artisan'); + + return new ArgvInput($subCommand); + } } diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index 7415b74f..19018c9a 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -16,6 +16,7 @@ use Stancl\Tenancy\Listeners\BootstrapTenancy; use Stancl\Tenancy\Listeners\RevertToCentralContext; use Stancl\Tenancy\Tests\Etc\ExampleSeeder; use Stancl\Tenancy\Tests\Etc\Tenant; +use Stancl\Tenancy\Tests\Etc\User; beforeEach(function () { Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { @@ -179,6 +180,29 @@ test('run command with array of tenants works', function () { ->expectsOutput('Tenant: ' . $tenantId2); }); +test('run command works when sub command asks questions and accepts arguments', function () { + $tenant = Tenant::create(); + $id = $tenant->getTenantKey(); + + Artisan::call('tenants:migrate'); + + pest()->artisan("tenants:run --tenants=$id 'user:addwithname Abrar' ") + ->expectsQuestion('What is your email?', 'email@localhost') + ->expectsOutput("Tenant: $id") + ->expectsOutput("User created: Abrar(email@localhost)"); + + // Assert we are in central context + expect(tenancy()->initialized)->toBeFalse(); + + // Assert user was created in tenant context + tenancy()->initialize($tenant); + $user = User::first(); + + // Assert user is same as provided using the command + expect($user->name)->toBe('Abrar'); + expect($user->email)->toBe('email@localhost'); +}); + // todo@tests function runCommandWorks(): void { diff --git a/tests/Etc/AddUserCommand.php b/tests/Etc/Console/AddUserCommand.php similarity index 91% rename from tests/Etc/AddUserCommand.php rename to tests/Etc/Console/AddUserCommand.php index 46e1fcbb..f102bae6 100644 --- a/tests/Etc/AddUserCommand.php +++ b/tests/Etc/Console/AddUserCommand.php @@ -2,12 +2,13 @@ declare(strict_types=1); -namespace Stancl\Tenancy\Tests\Etc; +namespace Stancl\Tenancy\Tests\Etc\Console; use Illuminate\Console\Command; use Illuminate\Support\Str; use Stancl\Tenancy\Concerns\HasATenantsOption; use Stancl\Tenancy\Concerns\TenantAwareCommand; +use Stancl\Tenancy\Tests\Etc\User; class AddUserCommand extends Command { diff --git a/tests/Etc/ConsoleKernel.php b/tests/Etc/Console/ConsoleKernel.php similarity index 72% rename from tests/Etc/ConsoleKernel.php rename to tests/Etc/Console/ConsoleKernel.php index a548f113..c5e5ee85 100644 --- a/tests/Etc/ConsoleKernel.php +++ b/tests/Etc/Console/ConsoleKernel.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Stancl\Tenancy\Tests\Etc; +namespace Stancl\Tenancy\Tests\Etc\Console; use Orchestra\Testbench\Foundation\Console\Kernel; @@ -10,6 +10,7 @@ class ConsoleKernel extends Kernel { protected $commands = [ ExampleCommand::class, + ExampleQuestionCommand::class, AddUserCommand::class, ]; } diff --git a/tests/Etc/ExampleCommand.php b/tests/Etc/Console/ExampleCommand.php similarity index 94% rename from tests/Etc/ExampleCommand.php rename to tests/Etc/Console/ExampleCommand.php index 49e7189b..72263b37 100644 --- a/tests/Etc/ExampleCommand.php +++ b/tests/Etc/Console/ExampleCommand.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Stancl\Tenancy\Tests\Etc; +namespace Stancl\Tenancy\Tests\Etc\Console; use Illuminate\Console\Command; diff --git a/tests/Etc/Console/ExampleQuestionCommand.php b/tests/Etc/Console/ExampleQuestionCommand.php new file mode 100644 index 00000000..9a967054 --- /dev/null +++ b/tests/Etc/Console/ExampleQuestionCommand.php @@ -0,0 +1,46 @@ +ask('What is your email?'); + + User::create([ + 'name' => $this->argument('name'), + 'email' => $email, + 'email_verified_at' => now(), + 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'remember_token' => Str::random(10), + ]); + + $this->line("User created: ". $this->argument('name') . "($email)"); + + return 0; + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index 67029422..ed567497 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -142,7 +142,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase */ protected function resolveApplicationConsoleKernel($app) { - $app->singleton('Illuminate\Contracts\Console\Kernel', Etc\ConsoleKernel::class); + $app->singleton('Illuminate\Contracts\Console\Kernel', Etc\Console\ConsoleKernel::class); } public function randomString(int $length = 10)