string('codigo')->primary(); }); Schema::create('attribute', function (Blueprint $table): void { $table->id(); $table->string('tenant_codigo'); $table->string('codigo'); $table->string('nombre'); $table->boolean('is_required')->default(false); $table->json('metadata_schema')->nullable(); $table->string('type'); $table->timestamps(); $table->unique(['tenant_codigo', 'codigo']); }); Schema::create('attribute_options', function (Blueprint $table): void { $table->id(); $table->foreignId('attribute_id')->constrained('attribute')->cascadeOnDelete(); $table->string('value'); $table->string('label'); $table->unsignedInteger('sort_order')->default(0); $table->json('metadata')->nullable(); $table->timestamps(); }); } protected function tearDown(): void { Schema::dropIfExists('attribute_options'); Schema::dropIfExists('attribute'); Schema::dropIfExists('tenants'); parent::tearDown(); } public function test_it_creates_the_attributes_and_options_idempotently(): void { $this->createTenant('mutual_smep'); $this->seed(MutualSmepAttributeSeeder::class); $this->seed(MutualSmepAttributeSeeder::class); $this->assertSame(5, DB::table('attribute')->where('tenant_codigo', 'mutual_smep')->count()); $this->assertSame(25, DB::table('attribute_options')->count()); $this->assertDatabaseHas('attribute', [ 'tenant_codigo' => 'mutual_smep', 'codigo' => 'medida_cama', 'nombre' => 'Medida', 'type' => 'select', 'is_required' => false, ]); $this->assertDatabaseHas('attribute_options', [ 'value' => '512 GB', 'label' => '512 GB', ]); } public function test_down_only_removes_mutual_smep_attributes(): void { $this->createTenant('mutual_smep'); $this->createTenant('other'); DB::table('attribute')->insert([ 'tenant_codigo' => 'other', 'codigo' => 'color', 'nombre' => 'Color', 'type' => 'select', 'created_at' => now(), 'updated_at' => now(), ]); $seeder = app(MutualSmepAttributeSeeder::class); $seeder->run(); $seeder->down(); $this->assertDatabaseMissing('attribute', ['tenant_codigo' => 'mutual_smep']); $this->assertDatabaseHas('attribute', [ 'tenant_codigo' => 'other', 'codigo' => 'color', ]); } public function test_the_data_migration_runs_and_rolls_back_the_attributes(): void { $this->createTenant('mutual_smep'); $migration = require database_path( 'migrations/2026_09_24_020000_seed_mutual_smep_attributes.php' ); $migration->up(); $this->assertSame(5, DB::table('attribute')->where('tenant_codigo', 'mutual_smep')->count()); $this->assertSame(25, DB::table('attribute_options')->count()); $migration->down(); $this->assertDatabaseMissing('attribute', ['tenant_codigo' => 'mutual_smep']); $this->assertSame(0, DB::table('attribute_options')->count()); } private function createTenant(string $code): void { DB::table('tenants')->insert(['codigo' => $code]); } }