withoutVite(); Storage::fake('public'); Storage::fake('local'); } public function test_la_pagina_e_riservata_all_amministratore(): void { Role::findOr('utente', fn () => Role::create(['name' => 'utente', 'guard_name' => 'web'])); app(PermissionRegistrar::class)->forgetCachedPermissions(); $utente = User::create([ 'name' => 'Utente semplice', 'email' => 'utente@example.test', 'password' => 'password-di-prova', ]); $utente->assignRole('utente'); $this->actingAs($utente)->get(route('piantine.index'))->assertForbidden(); $this->actingAs($this->admin())->get(route('piantine.index'))->assertOk(); } public function test_il_kml_caricato_diventa_l_area_attiva(): void { $kml = <<<'XML' Area 13.35,38.11 13.37,38.11 13.37,38.13 13.35,38.11 XML; Livewire::actingAs($this->admin()) ->test(PiantineManager::class) ->set('kmlFile', UploadedFile::fake()->createWithContent('citta.kml', $kml)) ->call('caricaKml') ->assertHasNoErrors(); Storage::disk('local')->assertExists('piantine/area.geojson'); } public function test_un_file_che_non_e_kml_viene_rifiutato(): void { Livewire::actingAs($this->admin()) ->test(PiantineManager::class) ->set('kmlFile', UploadedFile::fake()->createWithContent('foto.png', 'binario')) ->call('caricaKml') ->assertHasErrors('kmlFile'); } /** * La cascata di prima si portava via il disegno insieme al territorio — e * l'import XML svuota `territori` in blocco a ogni ripristino. */ public function test_cancellare_il_territorio_lascia_in_piedi_la_piantina(): void { $territorio = Territorio::create(['numero' => '12', 'attivo' => true]); $mappa = $this->piantina(['territorio_id' => $territorio->id]); $territorio->forceDelete(); $this->assertDatabaseCount('territorio_mappe', 1); $this->assertNull($mappa->fresh()->territorio_id); } public function test_l_elenco_mostra_lo_stato_di_ogni_piantina(): void { [$territorio, $pubblicata] = $this->pubblicata('7'); $this->piantina(['nome' => 'Zona porto']); Livewire::actingAs($this->admin()) ->test(PiantineManager::class) ->assertSee('Terr. 7') ->assertSee('Zona porto') ->assertSee('Pubblicata') ->assertSee('Bozza') ->assertSee('Scollegata'); } public function test_i_filtri_separano_bozze_pubblicate_e_da_pubblicare(): void { [, $pubblicata] = $this->pubblicata('7'); [$t8, $modificata] = $this->pubblicata('8'); $t8->update(['confini' => 'cambiati dopo la pubblicazione']); $this->piantina(['nome' => 'Zona porto']); $componente = Livewire::actingAs($this->admin())->test(PiantineManager::class); $componente->set('filtro', 'pubblicate') ->assertViewHas('elenco', fn ($e) => $e->pluck('id')->all() === [$pubblicata->id]); $componente->set('filtro', 'da-pubblicare') ->assertViewHas('elenco', fn ($e) => $e->pluck('id')->all() === [$modificata->id]); $componente->set('filtro', 'scollegate') ->assertViewHas('elenco', fn ($e) => $e->count() === 1 && $e->first()->nome === 'Zona porto'); $componente->set('filtro', 'inventato') ->assertSet('filtro', 'tutte') ->assertViewHas('elenco', fn ($e) => $e->count() === 3); } public function test_la_ricerca_trova_numero_nome_e_zona(): void { $zona = \App\Models\Zona::create(['nome' => 'Litorale', 'attivo' => true]); $territorio = Territorio::create(['numero' => '12', 'attivo' => true, 'zona_id' => $zona->id]); $this->piantina(['territorio_id' => $territorio->id]); $this->piantina(['nome' => 'Zona porto']); Livewire::actingAs($this->admin()) ->test(PiantineManager::class) ->set('cerca', 'litor') ->assertViewHas('elenco', fn ($e) => $e->count() === 1 && $e->first()->territorio_id === $territorio->id) ->set('cerca', 'PORTO') ->assertViewHas('elenco', fn ($e) => $e->count() === 1 && $e->first()->nome === 'Zona porto'); } public function test_pubblica_apre_la_finestra_condivisa_solo_se_si_puo(): void { $territorio = Territorio::create(['numero' => '12', 'attivo' => true]); $collegata = $this->piantina(['territorio_id' => $territorio->id]); $scollegata = $this->piantina(['nome' => 'Zona porto']); Livewire::actingAs($this->admin()) ->test(PiantineManager::class) ->call('pubblica', $collegata->id) ->assertDispatchedTo(\App\Livewire\Piantine\Pubblicazione::class, 'pubblica-piantina', mappaId: $collegata->id); Livewire::actingAs($this->admin()) ->test(PiantineManager::class) ->call('pubblica', $scollegata->id) ->assertNotDispatched('pubblica-piantina') ->assertDispatched('avviso'); } public function test_eliminare_toglie_la_piantina_ma_non_il_territorio(): void { $territorio = Territorio::create(['numero' => '12', 'attivo' => true]); $mappa = $this->piantina(['territorio_id' => $territorio->id]); Livewire::actingAs($this->admin()) ->test(PiantineManager::class) ->call('elimina', $mappa->id) ->assertDispatched('avviso'); $this->assertDatabaseCount('territorio_mappe', 0); $this->assertNotNull($territorio->fresh()); } public function test_ripristinare_una_versione_riporta_la_piantina_da_pubblicare(): void { [$territorio, $mappa] = $this->pubblicata('7'); Storage::disk('public')->put('territori-pdf-versioni/vecchia.pdf', '%PDF-vecchia'); $versione = \App\Models\TerritorioPdfVersione::create([ 'territorio_id' => $territorio->id, 'pdf_path' => 'territori-pdf-versioni/vecchia.pdf', 'origine' => 'piantine', 'sostituito_il' => now()->subDay(), ]); Livewire::actingAs($this->admin()) ->test(PiantineManager::class) ->call('ripristinaVersione', $versione->id) ->assertDispatched('avviso'); $this->assertStringStartsWith('territori-pdf/ripristino-', $territorio->fresh()->pdf_path); $this->assertSame(TerritorioMappa::STATO_MODIFICATA, $mappa->fresh()->stato()); } /** Una piantina collegata e segnata come pubblicata, senza passare dal renderer. */ private function pubblicata(string $numero): array { $territorio = Territorio::create(['numero' => $numero, 'attivo' => true]); $pdf = 'territori-pdf/piantina-' . $territorio->id . '-20261001-120000.pdf'; Storage::disk('public')->put($pdf, '%PDF-piantina'); $territorio->update(['pdf_path' => $pdf]); $mappa = $this->piantina(['territorio_id' => $territorio->id]); $mappa->load('territorio.zona'); $mappa->update([ 'geojson_pubblicato' => $mappa->geojson, 'impronta_pubblicata' => $mappa->impronta(), 'pubblicata_at' => now(), ]); return [$territorio, $mappa->fresh()]; } private function piantina(array $valori = []): TerritorioMappa { return TerritorioMappa::create(array_merge([ 'geojson' => '{"type":"Polygon","coordinates":[[[13.35,38.11],[13.37,38.11],[13.37,38.13],[13.35,38.11]]]}', ], $valori)); } private function admin(): User { Role::firstOrCreate(['name' => 'amministratore', 'guard_name' => 'web']); app(PermissionRegistrar::class)->forgetCachedPermissions(); Setting::firstOrCreate([], ['congregazione_nome' => 'Congregazione di prova']); $utente = User::firstOrCreate( ['email' => 'admin@example.test'], ['name' => 'Amministratore', 'password' => 'password-di-prova'], ); $utente->assignRole('amministratore'); return $utente; } }