'Doomed', 'sku' => 'DOOMED-1', 'type' => ProductType::SIMPLE, 'status' => ProductStatus::PUBLISHED, 'is_visible' => true, 'manage_stock' => false, ]); Cart::create(['session_id' => 'doomed-cart']); $exit = Artisan::call(ShopReinstallCommand::class, ['--force' => true]); $output = Artisan::output(); $this->assertSame(0, $exit); $this->assertStringContainsString('Starting shop reinstallation', $output); $this->assertStringContainsString('Shop tables reinstalled successfully', $output); // Tables exist (migrations re-ran)… $this->assertTrue(Schema::hasTable('product_purchases')); $this->assertTrue(Schema::hasTable('product_stocks')); $this->assertTrue(Schema::hasTable('carts')); // …but the seeded rows are gone. $this->assertSame(0, Product::count()); $this->assertSame(0, Cart::count()); } #[Test] public function declining_either_confirmation_short_circuits_with_a_cancelled_message(): void { // First confirmation says "no" → command exits without touching tables. Product::create([ 'name' => 'Survivor', 'sku' => 'SURV-1', 'type' => ProductType::SIMPLE, 'status' => ProductStatus::PUBLISHED, 'is_visible' => true, 'manage_stock' => false, ]); $this->artisan(ShopReinstallCommand::class) ->expectsConfirmation('Are you absolutely sure you want to continue?', 'no') ->expectsOutputToContain('Operation cancelled.') ->assertExitCode(0); $this->assertSame(1, Product::count(), 'data survives a cancelled reinstall'); } #[Test] public function declining_the_second_confirmation_also_short_circuits(): void { // First confirm says "yes", second says "no" — the second guard kicks // in before any destructive work happens. Product::create([ 'name' => 'Also Survivor', 'sku' => 'SURV-2', 'type' => ProductType::SIMPLE, 'status' => ProductStatus::PUBLISHED, 'is_visible' => true, 'manage_stock' => false, ]); $this->artisan(ShopReinstallCommand::class) ->expectsConfirmation('Are you absolutely sure you want to continue?', 'yes') ->expectsConfirmation('This action cannot be undone. Continue?', 'no') ->expectsOutputToContain('Operation cancelled.') ->assertExitCode(0); $this->assertSame(1, Product::count()); } #[Test] public function fresh_flag_is_synonymous_with_force_for_prompt_skipping(): void { // --fresh skips prompts just like --force; both are honoured by the // same `!force && !fresh` guard. Product::create([ 'name' => 'Doomed Too', 'sku' => 'DOOMED-2', 'type' => ProductType::SIMPLE, 'status' => ProductStatus::PUBLISHED, 'is_visible' => true, 'manage_stock' => false, ]); $exit = Artisan::call(ShopReinstallCommand::class, ['--fresh' => true]); $this->assertSame(0, $exit); $this->assertSame(0, Product::count()); } }