Files
termanager2/tests/Feature/SceltaRicercaTest.php
Francesco Picone fda428f242 ++ scelta di territori e proclamatori con ricerca
Al posto delle tendine (Assegna, Registro, editor delle piantine) un
campo in cui si scrive e compaiono le proposte più vicine: uguale, inizia
con, contiene, errore di battitura ("forse cercavi"); parole in qualsiasi
ordine, senza badare a maiuscole e accenti. Campo vuoto: la tendina
completa. Fatto anche per il telefono (16px, voci da 44px, scelta al tocco).

- Logica pura in resources/js/scelta.js con test node (tests/js).
- Opzioni dal server: Territorio/Proclamatore::opzioneScelta(); i
  territori già assegnati si trovano ("già assegnato a …") ma non si
  scelgono. Nomi cifrati ordinati e cercati decifrati, mai in SQL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 15:35:56 +02:00

159 lines
6.7 KiB
PHP

<?php
namespace Tests\Feature;
use App\Livewire\Assegnazioni\Assegna;
use App\Livewire\Piantine\PiantineEditor;
use App\Livewire\Registro;
use App\Models\AnnoTeocratico;
use App\Models\Assegnazione;
use App\Models\Proclamatore;
use App\Models\Setting;
use App\Models\Territorio;
use App\Models\TerritorioMappa;
use App\Models\User;
use App\Models\Zona;
use Database\Seeders\RolesAndPermissionsSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
use Tests\TestCase;
/**
* I campi di scelta con ricerca (<x-scelta>) per territori e proclamatori:
* le opzioni che il server prepara. Il modo in cui si filtrano e ordinano
* mentre si scrive è provato in tests/js/scelta.test.mjs.
*/
class SceltaRicercaTest extends TestCase
{
use RefreshDatabase;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->withoutVite();
Storage::fake('public');
Storage::fake('local');
$this->seed(RolesAndPermissionsSeeder::class);
Setting::firstOrCreate([], ['congregazione_nome' => 'Congregazione di prova']);
AnnoTeocratico::create(['label' => '2026-2027', 'start_date' => '2026-09-01', 'end_date' => '2027-08-31']);
$this->admin = User::create(['name' => 'Admin', 'email' => 'admin@example.test', 'password' => 'password-di-prova']);
$this->admin->assignRole('amministratore');
}
private function etichette(array $opzioni): array
{
return array_column($opzioni, 'etichetta');
}
public function test_assegna_usa_i_campi_con_ricerca(): void
{
$this->actingAs($this->admin)
->get(route('assegnazioni.assegna'))
->assertOk()
->assertSee('role="combobox"', false)
->assertSee('id="territorio_id"', false)
->assertSee('id="proclamatore_id"', false)
->assertDontSee('Filtra territori');
}
public function test_un_territorio_gia_assegnato_si_trova_ma_non_si_sceglie(): void
{
$zona = Zona::create(['nome' => 'Zisa', 'attivo' => true]);
$libero = Territorio::create(['numero' => '12', 'attivo' => true, 'zona_id' => $zona->id]);
$occupato = Territorio::create(['numero' => '35', 'attivo' => true]);
$mario = Proclamatore::create(['nome' => 'Mario', 'cognome' => 'Rossi', 'attivo' => true]);
Assegnazione::create([
'territorio_id' => $occupato->id, 'proclamatore_id' => $mario->id,
'anno_teocratico_id' => AnnoTeocratico::sole()->id, 'assigned_at' => now(), 'created_by' => $this->admin->id,
]);
$opzioni = Livewire::actingAs($this->admin)->test(Assegna::class)->viewData('opzioniTerritori');
$perValore = collect($opzioni)->keyBy('valore');
$this->assertSame(['valore' => (string) $libero->id, 'etichetta' => 'N° 12', 'dettaglio' => 'Zisa', 'chiavi' => ['12', 'Zisa', '']], $perValore[(string) $libero->id]);
$this->assertSame('già assegnato a Rossi Mario', $perValore[(string) $occupato->id]['motivo']);
$this->assertArrayNotHasKey('motivo', $perValore[(string) $libero->id]);
}
public function test_i_territori_sono_in_ordine_numerico(): void
{
foreach (['100', '9', '35', '12a', '12'] as $numero) {
Territorio::create(['numero' => $numero, 'attivo' => true]);
}
$opzioni = Livewire::actingAs($this->admin)->test(Assegna::class)->viewData('opzioniTerritori');
$this->assertSame(['N° 9', 'N° 12', 'N° 12a', 'N° 35', 'N° 100'], $this->etichette($opzioni));
}
public function test_i_proclamatori_sono_in_ordine_di_cognome_decifrato(): void
{
// Nel database sono cifrati: un ORDER BY li metterebbe a caso.
Proclamatore::create(['nome' => 'Paolo', 'cognome' => 'Verdi', 'attivo' => true]);
Proclamatore::create(['nome' => 'Anna', 'cognome' => 'Rosselli', 'attivo' => true]);
Proclamatore::create(['nome' => 'Luca', 'cognome' => 'Bianchi', 'attivo' => true]);
$opzioni = Livewire::actingAs($this->admin)->test(Assegna::class)->viewData('opzioniProclamatori');
$this->assertSame(['Bianchi Luca', 'Rosselli Anna', 'Verdi Paolo'], $this->etichette($opzioni));
$this->assertSame(['Bianchi', 'Luca'], $opzioni[0]['chiavi']);
}
public function test_assegna_propone_solo_proclamatori_attivi(): void
{
Proclamatore::create(['nome' => 'Mario', 'cognome' => 'Rossi', 'attivo' => true]);
Proclamatore::create(['nome' => 'Anna', 'cognome' => 'Verdi', 'attivo' => false]);
$opzioni = Livewire::actingAs($this->admin)->test(Assegna::class)->viewData('opzioniProclamatori');
$this->assertSame(['Rossi Mario'], $this->etichette($opzioni));
}
public function test_si_assegna_con_il_valore_scelto_nel_campo(): void
{
// Il campo manda a Livewire il valore come stringa, come faceva <select>.
Storage::disk('public')->put('territori-pdf/t7.pdf', '%PDF-1.4');
$territorio = Territorio::create(['numero' => '7', 'attivo' => true, 'pdf_path' => 'territori-pdf/t7.pdf']);
$mario = Proclamatore::create(['nome' => 'Mario', 'cognome' => 'Rossi', 'attivo' => true]);
Livewire::actingAs($this->admin)->test(Assegna::class)
->set('territorio_id', (string) $territorio->id)
->set('proclamatore_id', (string) $mario->id)
->call('save')
->assertHasNoErrors();
$this->assertSame($mario->id, Assegnazione::sole()->proclamatore_id);
}
public function test_nel_registro_i_disattivati_ci_sono_ma_non_si_scelgono(): void
{
Territorio::create(['numero' => '5', 'attivo' => false]);
Proclamatore::create(['nome' => 'Anna', 'cognome' => 'Verdi', 'attivo' => false]);
$pagina = Livewire::actingAs($this->admin)->test(Registro::class);
$this->assertSame('territorio disattivato', $pagina->viewData('opzioniTerritori')[0]['motivo']);
$this->assertSame('non attivo', $pagina->viewData('opzioniProclamatori')[0]['motivo']);
}
public function test_nell_editor_le_voci_fisse_restano_in_cima(): void
{
Territorio::create(['numero' => '12', 'attivo' => true]);
$mappa = TerritorioMappa::create(['geojson' => json_encode([
'type' => 'Polygon', 'coordinates' => [[[13.35, 38.11], [13.37, 38.11], [13.37, 38.13], [13.35, 38.11]]],
])]);
$opzioni = Livewire::actingAs($this->admin)
->test(PiantineEditor::class, ['mappa' => $mappa->id])
->viewData('opzioniTerritori');
$this->assertSame(['— nessun territorio —', '+ Crea un territorio nuovo', 'Territorio 12'], $this->etichette($opzioni));
$this->assertTrue($opzioni[0]['speciale']);
$this->assertSame('', $opzioni[0]['valore']);
}
}