Files
termanager2/tests/Feature/UltimoAmministratoreTest.php
Francesco Picone d433c9392d S-13 sul modulo ufficiale e correzioni all'integrità dei dati
Modulo S-13
- Il PDF scrive sopra il modulo ufficiale (FPDI, matrice convertita in PDF 1.4)
  invece di ricostruirlo in HTML: 20 righe per foglio come l'originale.
- Una riga per ogni territorio attivo; riporto dell'ultimo rientro prima
  dell'anno; assegnazioni a cavallo d'anno su entrambi i fogli; scelta per
  data e non per anno registrato; nomi come "Cognome I.".
- Logica spostata in App\Services\Registro\ModuloS13.

Integrità dei dati
- Export/import XML (e quindi backup/ripristino): le date non slittano più di
  un giorno; i file vecchi in UTC tornano al giorno giusto.
- Import XML: rifiuta file estranei o incompleti senza toccare i dati, errore
  con riga e motivo, territori senza zona importati con il loro storico,
  caratteri di controllo rimossi in export, chi importa conserva password e
  ruolo di amministratore.
- Assegnazioni: assegnazioneCorrente corretta (filtro dentro ofMany), periodi
  sovrapposti rifiutati in Assegna e Registro sotto lock, anno di servizio
  ricavato dalla data, niente date future nel Registro.
- Utenti: non si declassa sé stessi né l'ultimo amministratore.
- Entrypoint: non sovrascrive più la copia persistente di APP_KEY con un
  valore diverso; serve APP_KEY_ROTATE=1 per un cambio voluto.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:35:51 +02:00

79 lines
2.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Livewire\Settings\UsersIndex;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
/** L'installazione non deve mai restare senza un amministratore. */
class UltimoAmministratoreTest extends TestCase
{
use RefreshDatabase;
private User $admin;
protected function setUp(): void
{
parent::setUp();
Role::create(['name' => 'amministratore', 'guard_name' => 'web']);
Role::create(['name' => 'assistente', 'guard_name' => 'web']);
$this->admin = User::create(['name' => 'Admin', 'email' => 'admin@example.test', 'password' => 'password']);
$this->admin->assignRole('amministratore');
$this->actingAs($this->admin);
}
public function test_non_si_toglie_a_se_stessi_il_ruolo_di_amministratore(): void
{
// Anche con un secondo amministratore: il declassamento di sé stessi
// va chiesto a un altro.
User::create(['name' => 'Altro', 'email' => 'altro@example.test', 'password' => 'password'])
->assignRole('amministratore');
$this->modificaRuolo($this->admin, 'assistente')->assertHasErrors('editSelectedRole');
$this->assertTrue($this->admin->fresh()->hasRole('amministratore'));
}
public function test_non_si_declassa_l_ultimo_amministratore(): void
{
// Chi modifica non è l'amministratore stesso, così la regola su sé
// stessi non entra in gioco: si prova solo quella sull'ultimo. Il
// permesso della pagina sta nel middleware della rotta, che
// Livewire::test non attraversa.
$operatore = User::create(['name' => 'Operatore', 'email' => 'op@example.test', 'password' => 'password']);
$operatore->assignRole('assistente');
$this->actingAs($operatore);
$this->modificaRuolo($this->admin, 'assistente')->assertHasErrors('editSelectedRole');
$this->assertTrue($this->admin->fresh()->hasRole('amministratore'));
}
public function test_un_amministratore_ne_declassa_un_altro_se_non_e_l_ultimo(): void
{
$altro = User::create(['name' => 'Altro', 'email' => 'altro@example.test', 'password' => 'password']);
$altro->assignRole('amministratore');
$this->modificaRuolo($altro, 'assistente')->assertHasNoErrors();
$this->assertTrue($altro->fresh()->hasRole('assistente'));
$this->assertFalse($altro->fresh()->hasRole('amministratore'));
}
private function modificaRuolo(User $utente, string $ruolo)
{
return Livewire::test(UsersIndex::class)
->set('editingUserId', $utente->id)
->set('editName', $utente->name)
->set('editEmail', $utente->email)
->set('editSelectedRole', $ruolo)
->call('updateUser');
}
}