From 93bc9cf2fe5d479a9a3a88d6948bb41e4f88f8e3 Mon Sep 17 00:00:00 2001 From: Francesco Picone Date: Mon, 19 Oct 2026 17:59:31 +0200 Subject: [PATCH] ++ gruppi: vista del sorvegliante compilabile, azzeramento completo, test sistemati Nella vista Il mio gruppo un @php(...) in linea prima di un blocco @php ... @endphp mandava in errore il compilatore di Blade. L'azzeramento dell'applicazione ora cancella anche i gruppi di servizio. Co-Authored-By: Claude Opus 5.5 --- app/Jobs/ResetApplication.php | 4 ++- .../livewire/gruppi/mio-gruppo.blade.php | 6 ++-- tests/Feature/GruppiServizioTest.php | 28 +++++++++++++++---- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/app/Jobs/ResetApplication.php b/app/Jobs/ResetApplication.php index 0844173..9698758 100644 --- a/app/Jobs/ResetApplication.php +++ b/app/Jobs/ResetApplication.php @@ -5,6 +5,7 @@ namespace App\Jobs; use App\Models\AnnoTeocratico; use App\Models\Assegnazione; use App\Models\Campagna; +use App\Models\GruppoServizio; use App\Models\Proclamatore; use App\Models\Setting; use App\Models\Territorio; @@ -75,7 +76,7 @@ class ResetApplication implements ShouldQueue $stato->avanza($this->operationId, 1); $stato->log($this->operationId, $fileRimossi . ' file rimossi dal disco.'); - $stato->fase($this->operationId, 'Cancellazione dei dati gestionali', 10); + $stato->fase($this->operationId, 'Cancellazione dei dati gestionali', 11); DB::transaction(function () use ($stato) { $passi = [ @@ -87,6 +88,7 @@ class ResetApplication implements ShouldQueue 'Piantine' => fn () => TerritorioMappa::query()->delete(), 'Storico dei PDF' => fn () => TerritorioPdfVersione::query()->delete(), 'Territori' => fn () => Territorio::query()->withTrashed()->forceDelete(), + 'Gruppi di servizio' => fn () => GruppoServizio::query()->delete(), 'Proclamatori' => fn () => Proclamatore::query()->withTrashed()->forceDelete(), 'Tipologie' => fn () => Tipologia::query()->delete(), 'Zone' => fn () => Zona::query()->delete(), diff --git a/resources/views/livewire/gruppi/mio-gruppo.blade.php b/resources/views/livewire/gruppi/mio-gruppo.blade.php index c23f5d8..6f3c47c 100644 --- a/resources/views/livewire/gruppi/mio-gruppo.blade.php +++ b/resources/views/livewire/gruppi/mio-gruppo.blade.php @@ -10,7 +10,9 @@ @else

Gruppo {{ $gruppo->nome }}

- @php($daDare = $territori->filter(fn ($t) => ! $t->assegnazioneCorrente)->count()) + {{-- In questa vista solo blocchi php…endphp: la forma in linea, se + viene prima di un blocco, confonde il compilatore di Blade. --}} + @php $daDare = $territori->filter(fn ($t) => ! $t->assegnazioneCorrente)->count(); @endphp

{{ $territori->count() }} {{ $territori->count() === 1 ? 'territorio' : 'territori' }} nel pacchetto · {{ $daDare }} da dare · {{ $membri->count() }} {{ $membri->count() === 1 ? 'membro' : 'membri' }} @@ -109,7 +111,7 @@

Membri del gruppo

    @foreach($membri as $m) - @php($quanti = $territori->filter(fn ($t) => $t->assegnazioneCorrente?->proclamatore_id === $m->id)->count()) + @php $quanti = $territori->filter(fn ($t) => $t->assegnazioneCorrente?->proclamatore_id === $m->id)->count(); @endphp
  • {{ $m->nome_completo }} @if($m->id === $gruppo->sorvegliante_id)(sorvegliante)@endif {{ $quanti }} {{ $quanti === 1 ? 'territorio' : 'territori' }} diff --git a/tests/Feature/GruppiServizioTest.php b/tests/Feature/GruppiServizioTest.php index 08981eb..c97e2e8 100644 --- a/tests/Feature/GruppiServizioTest.php +++ b/tests/Feature/GruppiServizioTest.php @@ -71,10 +71,12 @@ class GruppiServizioTest extends TestCase [$gruppo, $password] = app(GruppiServizio::class)->crea('Zisa', $rossi, 'mario@example.test', [$verdi->id, $bianchi->id]); $territori = collect(['12', '14', '35'])->map(fn ($n) => $this->territorio($n)); app(GruppiServizio::class)->aggiungiAlPacchetto($gruppo, $territori->pluck('id')->all()); + $territori = $territori->map->fresh(); $sorvegliante = User::where('email', 'mario@example.test')->sole(); // Il cambio password al primo accesso ha i suoi test: qui si lavora. - $sorvegliante->forceFill(['password_change_required' => false])->save(); + // E l'email non confermata, come nella realtà (TestCase le conferma). + $sorvegliante->forceFill(['password_change_required' => false, 'email_verified_at' => null])->save(); return compact('gruppo', 'password', 'rossi', 'verdi', 'bianchi', 'territori', 'sorvegliante'); } @@ -100,9 +102,10 @@ class GruppiServizioTest extends TestCase $this->assertSame($rossi->id, $utente->proclamatore_id); $this->assertTrue($utente->hasRole('sorvegliante')); $this->assertTrue($utente->password_change_required); - // Nessuna conferma dell'email per il sorvegliante. - $this->assertNull($utente->email_verified_at); - $this->assertTrue($utente->hasVerifiedEmail()); + // Nessuna conferma dell'email per il sorvegliante (TestCase conferma + // gli utenti creati: qui si toglie). + $utente->forceFill(['email_verified_at' => null])->save(); + $this->assertTrue($utente->fresh()->hasVerifiedEmail()); // La password temporanea si vede una volta, ed è quella vera. $password = $pagina->get('passwordTemporanea'); @@ -420,7 +423,22 @@ class GruppiServizioTest extends TestCase } } - // ─── Backup ───────────────────────────────────────────────── + // ─── Backup e azzeramento ─────────────────────────────────── + + public function test_l_azzeramento_toglie_anche_gruppi_e_utenza_del_sorvegliante(): void + { + ['gruppo' => $gruppo, 'verdi' => $verdi, 'territori' => $territori, 'sorvegliante' => $s] = $this->gruppo(); + app(GruppiServizio::class)->assegna($gruppo, $territori[0], $verdi, now()); + + $stato = app(\App\Services\BackupOperationState::class); + $stato->initialize('azzeramento-gruppi', 'azzeramento', 'In attesa'); + (new \App\Jobs\ResetApplication('azzeramento-gruppi', $this->admin->id))->handle($stato, app(\App\Services\BackupArchive::class)); + + $this->assertSame('completed', $stato->get('azzeramento-gruppi')['status'] ?? null, json_encode($stato->get('azzeramento-gruppi'))); + $this->assertSame(0, GruppoServizio::count()); + $this->assertNull(User::find($s->id)); + } + public function test_l_xml_conserva_gruppi_membri_pacchetto_e_utenza(): void {