171 lines
5.8 KiB
PHP
171 lines
5.8 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\AnnoTeocratico;
|
|
use App\Models\Assegnazione;
|
|
use App\Models\Campagna;
|
|
use App\Models\Proclamatore;
|
|
use App\Models\Setting;
|
|
use App\Models\Territorio;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use Spatie\Permission\Models\Role;
|
|
use Spatie\Permission\PermissionRegistrar;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* Ogni pagina dell'applicazione si apre davvero.
|
|
*
|
|
* Nasce dall'unificazione dello stile, che ha toccato tutte le viste: un errore
|
|
* di markup non fallisce come un errore di codice — non rompe niente finche'
|
|
* qualcuno non apre quella pagina, e con venti viste modificate in una volta
|
|
* "qualcuno" e' un utente, non chi ha fatto la modifica.
|
|
*
|
|
* Il controllo su `<x-` non e' teorico: un tag di componente che il compilatore
|
|
* non riconosce resta nella pagina come testo. Non solleva, non rompe il
|
|
* layout in modo evidente — semplicemente il pulsante non c'e'.
|
|
*/
|
|
class PagineApplicativeTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
// Gli asset compilati non stanno nell'immagine di test: vedi la nota in
|
|
// PaginaBackupImportTest.
|
|
$this->withoutVite();
|
|
}
|
|
|
|
/**
|
|
* Rotte senza parametri. Quelle con un modello nell'URL hanno un test a
|
|
* parte, perche' hanno bisogno che il modello esista.
|
|
*
|
|
* @return array<string, array{string}>
|
|
*/
|
|
public static function rotteSempliciProvider(): array
|
|
{
|
|
$rotte = [
|
|
'dashboard',
|
|
'profile',
|
|
'territori.index',
|
|
'territori.create',
|
|
'territori.cestino',
|
|
'proclamatori.index',
|
|
'proclamatori.create',
|
|
'proclamatori.cestino',
|
|
'campagne.index',
|
|
'campagne.create',
|
|
'registro.index',
|
|
'audit.index',
|
|
'settings.edit',
|
|
'users.index',
|
|
'zone.index',
|
|
'tipologie.index',
|
|
'xml.exchange',
|
|
'piantine.index',
|
|
'privacy',
|
|
'assegnazioni.assegna',
|
|
];
|
|
|
|
return array_combine(
|
|
$rotte,
|
|
array_map(fn (string $rotta) => [$rotta], $rotte)
|
|
);
|
|
}
|
|
|
|
#[DataProvider('rotteSempliciProvider')]
|
|
public function test_la_pagina_si_apre_senza_markup_rimasto_da_compilare(string $rotta): void
|
|
{
|
|
$risposta = $this->actingAs($this->admin())->get(route($rotta));
|
|
|
|
$risposta->assertOk();
|
|
|
|
$this->assertNessunTagDaCompilare($risposta->getContent(), $rotta);
|
|
}
|
|
|
|
public function test_le_pagine_legate_a_un_record_si_aprono(): void
|
|
{
|
|
$this->actingAs($this->admin());
|
|
|
|
$territorio = Territorio::create(['numero' => '1', 'attivo' => true]);
|
|
$proclamatore = Proclamatore::create(['nome' => 'Mario', 'cognome' => 'Rossi', 'attivo' => true]);
|
|
$campagna = Campagna::create([
|
|
'descrizione' => 'Campagna di prova',
|
|
'start_date' => '2026-01-01',
|
|
'end_date' => '2026-12-31',
|
|
]);
|
|
|
|
$assegnazione = Assegnazione::create([
|
|
'territorio_id' => $territorio->id,
|
|
'proclamatore_id' => $proclamatore->id,
|
|
'anno_teocratico_id' => AnnoTeocratico::corrente()->id,
|
|
'assigned_at' => '2026-02-01',
|
|
'created_by' => auth()->id(),
|
|
]);
|
|
|
|
$pagine = [
|
|
'territori.show' => route('territori.show', $territorio),
|
|
'territori.edit' => route('territori.edit', $territorio),
|
|
'proclamatori.show' => route('proclamatori.show', $proclamatore),
|
|
'proclamatori.edit' => route('proclamatori.edit', $proclamatore),
|
|
'campagne.show' => route('campagne.show', $campagna),
|
|
'campagne.edit' => route('campagne.edit', $campagna),
|
|
'assegnazioni.rientra' => route('assegnazioni.rientra', $assegnazione),
|
|
];
|
|
|
|
foreach ($pagine as $nome => $url) {
|
|
$risposta = $this->get($url);
|
|
|
|
$risposta->assertOk();
|
|
$this->assertNessunTagDaCompilare($risposta->getContent(), $nome);
|
|
}
|
|
}
|
|
|
|
public function test_la_schermata_di_cambio_password_si_apre(): void
|
|
{
|
|
$risposta = $this->actingAs($this->admin())->get(route('password.change'));
|
|
|
|
$risposta->assertOk();
|
|
$this->assertNessunTagDaCompilare($risposta->getContent(), 'password.change');
|
|
}
|
|
|
|
public function test_la_pagina_di_accesso_si_apre(): void
|
|
{
|
|
$risposta = $this->get(route('login'));
|
|
|
|
$risposta->assertOk();
|
|
$this->assertNessunTagDaCompilare($risposta->getContent(), 'login');
|
|
}
|
|
|
|
private function assertNessunTagDaCompilare(string $html, string $dove): void
|
|
{
|
|
$this->assertStringNotContainsString('<x-btn', $html, "{$dove}: tag <x-btn> rimasto da compilare.");
|
|
$this->assertStringNotContainsString('</x-btn>', $html, "{$dove}: tag </x-btn> rimasto da compilare.");
|
|
$this->assertStringNotContainsString('btn-action', $html, "{$dove}: e' rimasta una classe .btn-action, che non esiste piu' nel foglio di stile.");
|
|
}
|
|
|
|
private function admin(): User
|
|
{
|
|
Role::findOr('amministratore', fn () => Role::create(['name' => 'amministratore', 'guard_name' => 'web']));
|
|
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
|
|
|
// La testata legge le impostazioni: senza riga, il nome della
|
|
// congregazione ricade sul default e va bene lo stesso, ma le pagine
|
|
// che leggono le soglie vogliono trovarla.
|
|
Setting::firstOrCreate([], ['congregazione_nome' => 'Congregazione di prova']);
|
|
|
|
$utente = User::create([
|
|
'name' => 'Amministratore',
|
|
'email' => 'admin@example.test',
|
|
'password' => 'password-di-prova',
|
|
]);
|
|
$utente->assignRole('amministratore');
|
|
|
|
return $utente;
|
|
}
|
|
}
|