++ pagina Assegna più leggera; "Vedi tutti" in testata nella Home
Assegna pesava 387 KB e Livewire li rimandava a ogni interazione. - Elenco dei territori assegnati in un componente lazy a sé (ElencoAssegnati): il form compare subito e non lo ridisegna. - Ricerca nell'elenco e anteprima della miniatura nel browser: nessuna richiesta al server mentre si scrive o si sceglie il territorio. - Icone SVG come simboli richiamati con <use>. - Assegnazione::giorni: cast a int (Carbon 3 restituisce un float). Home: "Vedi tutti" diventa un pulsante nella testata dei riquadri. README e HANDOFF aggiornati. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
109
tests/Feature/AssegnaPrestazioniTest.php
Normal file
109
tests/Feature/AssegnaPrestazioniTest.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Livewire\Assegnazioni\Assegna;
|
||||
use App\Livewire\Assegnazioni\ElencoAssegnati;
|
||||
use App\Models\AnnoTeocratico;
|
||||
use App\Models\Assegnazione;
|
||||
use App\Models\Proclamatore;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Territorio;
|
||||
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;
|
||||
|
||||
/**
|
||||
* La pagina Assegna era lenta: ~400 KB rimandati per intero a ogni
|
||||
* interazione. Questi test tengono fermi i rimedi: elenco in un componente
|
||||
* lazy, ricerca e anteprima nel browser, righe leggere.
|
||||
*/
|
||||
class AssegnaPrestazioniTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
private User $admin;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->withoutVite();
|
||||
Storage::fake('public');
|
||||
$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');
|
||||
}
|
||||
|
||||
/** $n assegnazioni aperte, ognuna con PDF e un proclamatore con telefono. */
|
||||
private function assegnazioni(int $n): void
|
||||
{
|
||||
$zona = Zona::create(['nome' => 'Montepellegrino', 'attivo' => true]);
|
||||
for ($i = 1; $i <= $n; $i++) {
|
||||
Storage::disk('public')->put("territori-pdf/t{$i}.pdf", '%PDF-1.4');
|
||||
$t = Territorio::create(['numero' => (string) $i, 'attivo' => true, 'zona_id' => $zona->id, 'pdf_path' => "territori-pdf/t{$i}.pdf"]);
|
||||
$p = Proclamatore::create(['nome' => "Nicolò{$i}", 'cognome' => 'Rossi', 'attivo' => true, 'telefono' => '3331234567']);
|
||||
Assegnazione::create([
|
||||
'territorio_id' => $t->id, 'proclamatore_id' => $p->id, 'anno_teocratico_id' => AnnoTeocratico::sole()->id,
|
||||
'assigned_at' => now()->subDays($i), 'created_by' => $this->admin->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_la_pagina_non_contiene_piu_l_elenco_che_arriva_dopo(): void
|
||||
{
|
||||
$this->assegnazioni(5);
|
||||
|
||||
$this->actingAs($this->admin)
|
||||
->get(route('assegnazioni.assegna'))
|
||||
->assertOk()
|
||||
->assertSee('Caricamento dei territori assegnati')
|
||||
->assertDontSee('Territori Assegnati (5)');
|
||||
}
|
||||
|
||||
public function test_scegliere_un_territorio_non_chiede_niente_al_server(): void
|
||||
{
|
||||
$html = $this->actingAs($this->admin)->get(route('assegnazioni.assegna'))->getContent();
|
||||
|
||||
// wire:model senza .live: il valore parte solo con "Assegna".
|
||||
$this->assertStringContainsString('wire:model="territorio_id"', $html);
|
||||
$this->assertStringNotContainsString('wire:model.live="territorio_id"', $html);
|
||||
}
|
||||
|
||||
public function test_le_opzioni_portano_la_miniatura_per_l_anteprima(): void
|
||||
{
|
||||
$t = Territorio::create(['numero' => '7', 'attivo' => true, 'thumbnail_path' => 'territori-thumbnails/t7.png']);
|
||||
|
||||
$opzioni = Livewire::actingAs($this->admin)->test(Assegna::class)->viewData('opzioniTerritori');
|
||||
|
||||
$this->assertSame($t->miniaturaUrl(), $opzioni[0]['miniatura']);
|
||||
}
|
||||
|
||||
public function test_l_elenco_si_cerca_nel_browser_senza_accenti(): void
|
||||
{
|
||||
$this->assegnazioni(1);
|
||||
|
||||
Livewire::withoutLazyLoading()->actingAs($this->admin)->test(ElencoAssegnati::class)
|
||||
->assertSee('Territori Assegnati (1)')
|
||||
->assertSeeHtml('data-cerca="1 montepellegrino rossi nicolo1"')
|
||||
->assertDontSeeHtml('wire:model.live.debounce.300ms="linkSearch"');
|
||||
}
|
||||
|
||||
public function test_le_righe_dell_elenco_restano_leggere(): void
|
||||
{
|
||||
$this->assegnazioni(30);
|
||||
|
||||
$html = Livewire::withoutLazyLoading()->actingAs($this->admin)->test(ElencoAssegnati::class)->html();
|
||||
|
||||
// Prima ~3,8 KB a riga. Le icone sono simboli richiamati con <use>.
|
||||
$this->assertLessThan(2600, strlen($html) / 30, 'Ogni riga dell\'elenco deve restare sotto i 2,6 KB');
|
||||
$this->assertSame(1, substr_count($html, '<symbol id="tm-i-copia"'));
|
||||
$this->assertGreaterThanOrEqual(30, substr_count($html, 'href="#tm-i-copia"'));
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Livewire\Assegnazioni\Assegna;
|
||||
use App\Livewire\Assegnazioni\ElencoAssegnati;
|
||||
use App\Livewire\Proclamatori\ProclamatoreCreate;
|
||||
use App\Livewire\Settings\XmlExchange;
|
||||
use App\Models\AnnoTeocratico;
|
||||
@@ -245,11 +246,15 @@ class ContattiProclamatoriTest extends TestCase
|
||||
$this->assegna($mario, $this->territorioConPdf());
|
||||
$assegnazione = Assegnazione::sole();
|
||||
|
||||
// La pagina viene chiusa senza rispondere: l'invio è perso, l'avviso resta.
|
||||
// La pagina viene chiusa senza rispondere: l'invio è perso, l'avviso resta
|
||||
// nell'elenco, e "Invia link" chiede alla pagina di riaprirlo.
|
||||
Livewire::withoutLazyLoading()->actingAs($this->admin)->test(ElencoAssegnati::class)
|
||||
->assertSee('Link ancora da inviare')
|
||||
->assertSeeHtml("\$dispatch('apri-invio', { assegnazioneId: {$assegnazione->id} })");
|
||||
|
||||
Livewire::actingAs($this->admin)->test(Assegna::class)
|
||||
->assertSet('invioId', null)
|
||||
->assertSee('Link ancora da inviare')
|
||||
->call('apriInvio', $assegnazione->id)
|
||||
->dispatch('apri-invio', assegnazioneId: $assegnazione->id)
|
||||
->assertSee('Hai inviato il link?')
|
||||
->call('concludiInvio', false)
|
||||
->assertRedirect(route('assegnazioni.assegna'));
|
||||
@@ -260,7 +265,7 @@ class ContattiProclamatoriTest extends TestCase
|
||||
->assertSee('Il link della piantina è ancora da inviare');
|
||||
|
||||
// Segnato come inviato dall'elenco: l'avviso sparisce.
|
||||
Livewire::actingAs($this->admin)->test(Assegna::class)
|
||||
Livewire::withoutLazyLoading()->actingAs($this->admin)->test(ElencoAssegnati::class)
|
||||
->call('toggleLinkSent', $assegnazione->id)
|
||||
->assertDontSee('Link ancora da inviare');
|
||||
$this->assertFalse($assegnazione->fresh()->link_in_sospeso);
|
||||
|
||||
Reference in New Issue
Block a user