++ Prima versione del designer piantine + Skill grafica

This commit is contained in:
2026-08-28 15:32:14 +02:00
parent 8aa29cc467
commit 7e4c8aa9b8
62 changed files with 16340 additions and 4 deletions

View File

@@ -0,0 +1,187 @@
<?php
namespace Tests\Feature;
use App\Jobs\RigeneraPiantine;
use App\Livewire\Piantine\PiantineManager;
use App\Models\Setting;
use App\Models\Territorio;
use App\Models\TerritorioMappa;
use App\Models\User;
use App\Services\Piantine\PiantineOperationState;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;
use Tests\TestCase;
/**
* La pagina Piantine: accesso riservato, salvataggio dei poligoni disegnati,
* caricamento del KML e avvio della rigenerazione massiva.
*/
class PiantineManagerTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->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_poligono_disegnato_viene_salvato_sul_territorio(): void
{
$territorio = Territorio::create(['numero' => '12', 'attivo' => true]);
$geometry = [
'type' => 'Polygon',
'coordinates' => [[[13.35, 38.11], [13.37, 38.11], [13.37, 38.13], [13.35, 38.11]]],
];
Livewire::actingAs($this->admin())
->test(PiantineManager::class)
->set('territorioSelezionato', $territorio->id)
->dispatch('poligono-disegnato', geometry: $geometry)
->call('salvaPoligono');
$mappa = TerritorioMappa::sole();
$this->assertSame($territorio->id, $mappa->territorio_id);
$this->assertSame($geometry, $mappa->geometria());
}
public function test_ridisegnare_sostituisce_il_poligono_senza_duplicarlo(): void
{
$territorio = Territorio::create(['numero' => '12', 'attivo' => true]);
TerritorioMappa::create([
'territorio_id' => $territorio->id,
'geojson' => '{"type":"Polygon","coordinates":[[[0,0],[1,0],[1,1],[0,0]]]}',
]);
$nuova = ['type' => 'Polygon', 'coordinates' => [[[5, 5], [6, 5], [6, 6], [5, 5]]]];
Livewire::actingAs($this->admin())
->test(PiantineManager::class)
->set('territorioSelezionato', $territorio->id)
->dispatch('poligono-disegnato', geometry: $nuova)
->call('salvaPoligono');
$this->assertSame(1, TerritorioMappa::count());
$this->assertSame($nuova, TerritorioMappa::sole()->geometria());
}
public function test_una_geometria_non_valida_viene_ignorata(): void
{
$territorio = Territorio::create(['numero' => '12', 'attivo' => true]);
Livewire::actingAs($this->admin())
->test(PiantineManager::class)
->set('territorioSelezionato', $territorio->id)
->dispatch('poligono-disegnato', geometry: ['type' => 'Point', 'coordinates' => [1, 2]])
->call('salvaPoligono');
$this->assertSame(0, TerritorioMappa::count());
}
public function test_il_kml_caricato_diventa_l_area_attiva(): void
{
$kml = <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark>
<name>Area</name>
<Polygon><outerBoundaryIs><LinearRing>
<coordinates>13.35,38.11 13.37,38.11 13.37,38.13 13.35,38.11</coordinates>
</LinearRing></outerBoundaryIs></Polygon>
</Placemark></Document></kml>
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');
}
public function test_rigenera_tutto_accoda_il_job_e_inizializza_lo_stato(): void
{
Queue::fake();
$territorio = Territorio::create(['numero' => '3', 'attivo' => true]);
TerritorioMappa::create([
'territorio_id' => $territorio->id,
'geojson' => '{"type":"Polygon","coordinates":[[[0,0],[1,0],[1,1],[0,0]]]}',
]);
$componente = Livewire::actingAs($this->admin())
->test(PiantineManager::class)
->call('rigeneraTutto', true);
Queue::assertPushed(RigeneraPiantine::class, fn ($job) => $job->anchePdf === true);
$state = app(PiantineOperationState::class);
$operazioneId = $componente->get('operazioneId');
$this->assertNotNull($operazioneId);
$this->assertSame(1, $state->get($operazioneId)['total']);
// Con un'operazione aperta, un secondo avvio deve essere rifiutato.
$componente->call('rigeneraTutto', false);
Queue::assertPushed(RigeneraPiantine::class, 1);
}
public function test_rigenera_tutto_senza_poligoni_non_accoda_nulla(): void
{
Queue::fake();
Livewire::actingAs($this->admin())
->test(PiantineManager::class)
->call('rigeneraTutto', false);
Queue::assertNothingPushed();
}
private function admin(): User
{
Role::findOr('amministratore', fn () => Role::create(['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;
}
}