feat: Aggiungi funzionalità di eliminazione per clienti e preventivi con gestione delle dipendenze

This commit is contained in:
2026-10-19 15:48:15 +02:00
parent d6a9978167
commit 31d5152d8c
20 changed files with 673 additions and 17 deletions
@@ -0,0 +1,141 @@
<?php
namespace Tests\Feature;
use App\Mail\PreventivoCliente;
use App\Models\Cliente;
use App\Models\Preventivo;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Mail;
use Mockery;
use Tests\TestCase;
class ConfermaPreventivoTest extends TestCase
{
use RefreshDatabase;
/** Crea un preventivo in bozza con una riga, pronto per la conferma. */
private function creaCarrelloBozza(): Preventivo
{
$preventivo = Preventivo::create([
'token' => 'token-test-123',
'stato' => 'bozza',
'totale' => 0,
]);
$preventivo->items()->create([
'sistema' => 'pvc',
'type' => 'finestra_1_anta',
'nome_modello' => 'Finestra 1 anta',
'larghezza' => 100,
'altezza' => 100,
'quantita' => 1,
'prezzo_unitario' => 500,
'prezzo_totale' => 500,
'payload' => ['nome' => 'Finestra 1 anta'],
]);
$preventivo->ricalcolaTotale();
return $preventivo;
}
private function datiConferma(): array
{
return [
'nome' => 'Mario',
'cognome' => 'Rossi',
'ragione_sociale' => null,
'email' => 'mario.rossi@example.com',
'telefono' => '3331234567',
'indirizzo' => 'Via Roma 1',
'cap' => '20100',
'citta' => 'Milano',
'provincia' => 'MI',
'note' => null,
];
}
public function test_conferma_da_cliente_loggato_non_crea_un_nuovo_cliente(): void
{
Mockery::mock('alias:App\Support\PreventivoPdf')
->shouldReceive('genera')
->andReturn('preventivi/preventivo-1.pdf');
Mail::fake();
$cliente = Cliente::create([
'username' => 'user1234',
'password' => 'Segreta123!',
'nome' => 'Mario',
'cognome' => 'Bianchi',
'email' => 'mario.bianchi@example.com',
'telefono' => '3330000000',
]);
$token = $cliente->createToken('configuratore', ['*'])->plainTextToken;
$preventivo = $this->creaCarrelloBozza();
$dati = $this->datiConferma();
$dati['cognome'] = 'Rossi'; // diverso dal dato salvato: l'anagrafica deve aggiornarsi
$response = $this->postJson("/api/carrello/{$preventivo->token}/conferma", $dati, [
'Authorization' => "Bearer {$token}",
]);
$response->assertOk();
// Nessun nuovo utente creato: in database c'è ancora solo il cliente originale.
$this->assertSame(1, Cliente::count());
$preventivo->refresh();
$this->assertSame($cliente->id, $preventivo->cliente_id);
$this->assertSame('inviato', $preventivo->stato);
$this->assertNotNull($preventivo->numero);
// L'anagrafica del cliente loggato è aggiornata con i dati confermati nel form.
$this->assertSame('Rossi', $cliente->fresh()->cognome);
$this->assertSame('3331234567', $cliente->fresh()->telefono);
Mail::assertSent(PreventivoCliente::class);
}
public function test_conferma_da_guest_crea_il_cliente(): void
{
Mockery::mock('alias:App\Support\PreventivoPdf')
->shouldReceive('genera')
->andReturn('preventivi/preventivo-1.pdf');
Mail::fake();
$this->assertSame(0, Cliente::count());
$preventivo = $this->creaCarrelloBozza();
$response = $this->postJson("/api/carrello/{$preventivo->token}/conferma", $this->datiConferma());
$response->assertOk();
$this->assertSame(1, Cliente::count());
$preventivo->refresh();
$this->assertNotNull($preventivo->cliente_id);
$this->assertSame('mario.rossi@example.com', $preventivo->cliente->email);
}
public function test_conferma_con_token_non_valido_tratta_l_utente_come_guest(): void
{
Mockery::mock('alias:App\Support\PreventivoPdf')
->shouldReceive('genera')
->andReturn('preventivi/preventivo-1.pdf');
Mail::fake();
$preventivo = $this->creaCarrelloBozza();
$response = $this->postJson("/api/carrello/{$preventivo->token}/conferma", $this->datiConferma(), [
'Authorization' => 'Bearer token-non-esistente',
]);
$response->assertOk();
$this->assertSame(1, Cliente::count());
$this->assertNotNull($preventivo->fresh()->cliente_id);
}
}
@@ -0,0 +1,96 @@
<?php
namespace Tests\Feature;
use App\Filament\Resources\ClienteResource;
use App\Filament\Resources\ClienteResource\Pages\ListClientes;
use App\Filament\Resources\PreventivoResource;
use App\Models\Cliente;
use App\Models\Preventivo;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Str;
use Livewire\Livewire;
use Tests\TestCase;
/**
* L'eliminazione di un cliente (singola o massiva) deve ridirezionare alla
* lista: il reload di pagina fa ri-renderizzare la sidebar, aggiornando il
* badge "Preventivi" nella navigazione.
*/
class EliminazioneClienteTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->actingAs(User::factory()->create());
}
private function creaCliente(string $nome, string $username): Cliente
{
return Cliente::create([
'username' => $username,
'password' => 'Segreta123!',
'nome' => $nome,
'email' => strtolower($username).'@example.com',
]);
}
private function creaPreventivoInviato(Cliente $cliente): Preventivo
{
return Preventivo::create([
'cliente_id' => $cliente->id,
'token' => Str::random(40),
'stato' => 'inviato',
'totale' => 100,
]);
}
public function test_eliminazione_singola_ridireziona_alla_lista(): void
{
$cliente = $this->creaCliente('Mario', 'mario-test');
$preventivo = $this->creaPreventivoInviato($cliente);
Livewire::test(ListClientes::class)
->callTableAction('delete', $cliente)
->assertRedirect(ClienteResource::getUrl('index'));
$this->assertDatabaseMissing(Cliente::class, ['id' => $cliente->id]);
$this->assertDatabaseMissing(Preventivo::class, ['id' => $preventivo->id]);
}
public function test_eliminazione_massiva_ridireziona_alla_lista(): void
{
$primo = $this->creaCliente('Mario', 'mario-bulk');
$secondo = $this->creaCliente('Luigi', 'luigi-bulk');
$this->creaPreventivoInviato($primo);
$this->creaPreventivoInviato($secondo);
Livewire::test(ListClientes::class)
->callTableBulkAction('delete', [$primo, $secondo])
->assertRedirect(ClienteResource::getUrl('index'));
$this->assertSame(0, Cliente::count());
$this->assertSame(0, Preventivo::count());
}
public function test_badge_preventivi_aggiornato_dopo_eliminazione(): void
{
$conPreventivo = $this->creaCliente('Anna', 'anna-test');
$senzaPreventivi = $this->creaCliente('Piero', 'pier-test');
$this->creaPreventivoInviato($conPreventivo);
$this->creaPreventivoInviato($senzaPreventivi);
$this->assertSame(2, (int) PreventivoResource::getNavigationBadge());
Livewire::test(ListClientes::class)
->callTableAction('delete', $conPreventivo)
->assertRedirect(ClienteResource::getUrl('index'));
// Dopo l'eliminazione il conteggio ricalcolato dal database è aggiornato.
$this->assertSame(1, (int) PreventivoResource::getNavigationBadge());
}
}