insertOrIgnore(['id' => 1, 'nome' => 'Admin Test', 'cognome' => 'Test', 'created_at' => now(), 'updated_at' => now()]); DB::table('persone_unita_relazioni')->truncate(); DB::table('persone')->truncate(); $mirrorCount = DB::connection('gescon_import') ->table('condomin_mirror') ->where('cod_stabile', '0021') ->count(); if ($mirrorCount === 0) { Artisan::call('gescon:import-mirror-0021'); } Artisan::call('gescon:reconstruct-mirror-0021'); }); test('unita immobiliare page mounts without 500 or undefined property exception when canale_convocazione is null or missing', function () { $user = User::first() ?: User::factory()->create(); try { if (method_exists($user, 'assignRole')) { \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']); $user->assignRole('admin'); } } catch (\Throwable $e) {} $stabile = Stabile::where('codice_stabile', '0021')->first(); expect($stabile)->not->toBeNull(); Auth::login($user); $unit = UnitaImmobiliare::where('stabile_id', $stabile->id)->where('scala', 'A')->where('interno', '11')->first(); expect($unit)->not->toBeNull(); request()->merge(['unita_id' => $unit->id]); $page = new UnitaImmobiliarePage(); $page->mount(); expect($page->canaliComunicazione)->toBeArray(); expect(count($page->canaliComunicazione))->toBeGreaterThan(0); foreach ($page->canaliComunicazione as $item) { expect($item)->toHaveKeys(['id', 'nominativo', 'codice_fiscale', 'convocazione', 'verbali', 'solleciti']); expect($item['convocazione'])->not->toBeNull(); } }); test('unita 13 (0021-A-11) timeline preserves ATER historical and Benedetto Daniela current', function () { $stabile = Stabile::where('codice_stabile', '0021')->first(); expect($stabile)->not->toBeNull(); $unit = UnitaImmobiliare::where('stabile_id', $stabile->id)->where('scala', 'A')->where('interno', '11')->first(); expect($unit)->not->toBeNull(); $rels = DB::table('persone_unita_relazioni')->where('unita_id', $unit->id)->get(); expect($rels->count())->toBeGreaterThanOrEqual(2); $aterRel = $rels->firstWhere('attivo', 0); expect($aterRel)->not->toBeNull(); $benedettoRel = $rels->firstWhere('attivo', 1); expect($benedettoRel)->not->toBeNull(); $benedettoPerson = DB::table('persone')->where('id', $benedettoRel->persona_id)->first(); expect($benedettoPerson->cognome)->toBe('BENEDETTO'); expect($benedettoPerson->nome)->toBe('DANIELA'); }); test('unita immobiliare splits multiple concatenated emails into individual structured channels', function () { $user = User::first() ?: User::factory()->create(); try { if (method_exists($user, 'assignRole')) { \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']); $user->assignRole('admin'); } } catch (\Throwable $e) {} Auth::login($user); $stabile = Stabile::where('codice_stabile', '0021')->first(); expect($stabile)->not->toBeNull(); StabileContext::setActiveStabileId($user, $stabile->id); $unit = UnitaImmobiliare::where('stabile_id', $stabile->id)->where('scala', 'A')->where('interno', '11')->first(); expect($unit)->not->toBeNull(); // Create a persona with multiple concatenated emails $multiEmailPersona = \App\Models\Persona::create([ 'cognome' => 'MULTI EMAIL TEST SRL', 'nome' => '', 'email_principale' => 'info@test.it, amministrazione@test.it, pec@test.it', 'telefono_principale' => '061234567', 'attivo' => 1, ]); DB::table('persone_unita_relazioni')->insert([ 'unita_id' => $unit->id, 'persona_id' => $multiEmailPersona->id, 'tipo_relazione' => 'inquilino', 'data_inizio' => '2026-01-01', 'attivo' => 1, 'created_at' => now(), 'updated_at' => now(), ]); request()->merge(['unita_id' => $unit->id]); $page = new UnitaImmobiliarePage(); $page->mount(); $recapiti = $page->getRecapitiMulticanaleTableProperty(); expect($recapiti)->toBeArray(); $emails = array_values(array_filter($recapiti, fn($r) => $r['canale'] === 'Email')); expect(count($emails))->toBeGreaterThanOrEqual(3); foreach ($emails as $em) { expect($em['valore'])->not->toContain(','); expect($em['valore'])->not->toContain(';'); expect($em['action_url'])->toStartWith('mailto:'); } }); test('unita immobiliare protocollo comunicazioni returns valid structure', function () { $user = User::first() ?: User::factory()->create(); try { if (method_exists($user, 'assignRole')) { \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']); $user->assignRole('admin'); } } catch (\Throwable $e) {} Auth::login($user); $stabile = Stabile::where('codice_stabile', '0021')->first(); expect($stabile)->not->toBeNull(); StabileContext::setActiveStabileId($user, $stabile->id); $unit = UnitaImmobiliare::where('stabile_id', $stabile->id)->where('scala', 'A')->where('interno', '11')->first(); expect($unit)->not->toBeNull(); request()->merge(['unita_id' => $unit->id]); $page = new UnitaImmobiliarePage(); $page->mount(); $protocollo = $page->getProtocolloComunicazioniProperty(); expect($protocollo)->toBeArray(); }); test('unita immobiliare categorizes contacts into condomino and inquilino sub-tables and supports toggle', function () { $user = User::first() ?: User::factory()->create(); try { if (method_exists($user, 'assignRole')) { \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']); $user->assignRole('admin'); } } catch (\Throwable $e) {} Auth::login($user); $stabile = Stabile::where('codice_stabile', '0021')->first(); expect($stabile)->not->toBeNull(); StabileContext::setActiveStabileId($user, $stabile->id); $unit = UnitaImmobiliare::where('stabile_id', $stabile->id)->where('scala', 'A')->where('interno', '11')->first(); expect($unit)->not->toBeNull(); request()->merge(['unita_id' => $unit->id]); $page = new UnitaImmobiliarePage(); $page->mount(); $recapiti = $page->getRecapitiMulticanaleTableProperty(); expect($recapiti)->toBeArray(); foreach ($recapiti as $rec) { expect($rec)->toHaveKey('tipo_soggetto'); expect(['condomino', 'inquilino'])->toContain($rec['tipo_soggetto']); } $page->setRecapitiViewMode('inquilino'); expect($page->recapitiViewMode)->toBe('inquilino'); $page->setRecapitiViewMode('diviso'); expect($page->recapitiViewMode)->toBe('diviso'); }); test('situazione iniziale renders and loads conguagli apertura from dett_tab', function () { $user = User::first() ?: User::factory()->create(); try { if (method_exists($user, 'assignRole')) { \Spatie\Permission\Models\Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']); $user->assignRole('admin'); } } catch (\Throwable $e) {} Auth::login($user); $stabile = Stabile::where('codice_stabile', '0021')->first(); expect($stabile)->not->toBeNull(); StabileContext::setActiveStabileId($user, $stabile->id); $sitPage = new \App\Filament\Pages\Contabilita\SituazioneIniziale(); $sitPage->mount(); expect($sitPage->tab)->toBe('bilancio'); $sitPage->tab = 'conguagli'; expect($sitPage->tab)->toBe('conguagli'); });