feat(auth): attivazione servizio email google workspace netgescon e flusso cambio password autonomo
This commit is contained in:
parent
00d4417dc7
commit
a0c441638e
61
app/Console/Commands/SendPasswordResetEmailCommand.php
Normal file
61
app/Console/Commands/SendPasswordResetEmailCommand.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Notifications\NetGesconResetPasswordNotification;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
class SendPasswordResetEmailCommand extends Command
|
||||
{
|
||||
protected $signature = 'netgescon:send-password-reset {email : Indirizzo email dell\'utente}';
|
||||
|
||||
protected $description = 'Invia l\'email con il link di reimpostazione password a un utente registrato su NetGescon';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$email = trim((string) $this->argument('email'));
|
||||
|
||||
$this->info("Verifica esistenza utente per email: {$email}...");
|
||||
|
||||
$user = User::query()->where('email', $email)->first();
|
||||
|
||||
if (! $user instanceof User) {
|
||||
$this->error("Errore: nessun utente trovato con l'indirizzo email {$email}.");
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info("Utente trovato: {$user->name} (ID: {$user->id}, Ruoli: " . $user->roles->pluck('name')->join(', ') . ")");
|
||||
|
||||
$broker = Password::broker(Filament::getAuthPasswordBroker());
|
||||
$token = $broker->createToken($user);
|
||||
|
||||
$notification = app(NetGesconResetPasswordNotification::class, ['token' => $token]);
|
||||
|
||||
try {
|
||||
$panel = Filament::getPanel('admin-filament');
|
||||
$url = $panel->getResetPasswordUrl($token, $user);
|
||||
} catch (\Throwable) {
|
||||
$url = url(route('filament.admin-filament.auth.password-reset.reset', [
|
||||
'token' => $token,
|
||||
'email' => $user->getEmailForPasswordReset(),
|
||||
], false));
|
||||
}
|
||||
|
||||
$notification->url = $url;
|
||||
|
||||
$this->info("Invio email in corso a {$email} via SMTP (Google Workspace / NetGescon)...");
|
||||
|
||||
try {
|
||||
$user->notify($notification);
|
||||
$this->info("Email inviata con successo!");
|
||||
$this->line("Link di ripristino generato: {$url}");
|
||||
return self::SUCCESS;
|
||||
} catch (\Throwable $e) {
|
||||
$this->error("Errore durante l'invio dell'email: " . $e->getMessage());
|
||||
return self::FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
app/Console/Commands/TestMailCommand.php
Normal file
41
app/Console/Commands/TestMailCommand.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class TestMailCommand extends Command
|
||||
{
|
||||
protected $signature = 'netgescon:test-mail {email=netgescon@gmail.com : Destinatario di test}';
|
||||
|
||||
protected $description = 'Verifica la connessione SMTP Google Workspace / NetGescon e invia un\'email di diagnostica';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$recipient = trim((string) $this->argument('email'));
|
||||
|
||||
$this->info("Diagnostica Configurazione Posta NetGescon:");
|
||||
$this->line("- MAILER: " . config('mail.default'));
|
||||
$this->line("- HOST: " . config('mail.mailers.smtp.host') . ":" . config('mail.mailers.smtp.port'));
|
||||
$this->line("- USERNAME: " . config('mail.mailers.smtp.username'));
|
||||
$this->line("- MITTENTE: " . config('mail.from.address') . " (" . config('mail.from.name') . ")");
|
||||
$this->line("- CODA (QUEUE_CONNECTION): " . config('queue.default'));
|
||||
$this->line("- DESTINATARIO TEST: " . $recipient);
|
||||
|
||||
$this->info("Invio in corso...");
|
||||
|
||||
try {
|
||||
Mail::raw("Questa e un'email di diagnostica inviata dal server NetGescon (.205) per confermare la corretta attivazione del servizio SMTP con account Google Workspace ({$recipient}). Data/ora: " . now()->toIso8601String(), function ($message) use ($recipient) {
|
||||
$message->to($recipient)
|
||||
->subject('NetGescon - Test Connessione Servizio Email');
|
||||
});
|
||||
|
||||
$this->info("Email di test recapitata con successo a {$recipient}!");
|
||||
return self::SUCCESS;
|
||||
} catch (\Throwable $e) {
|
||||
$this->error("Errore invio email: " . $e->getMessage());
|
||||
return self::FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,6 +192,17 @@ public function canAccessPanel(Panel $panel): bool
|
|||
]);
|
||||
}
|
||||
|
||||
public function sendPasswordResetNotification($token): void
|
||||
{
|
||||
$notification = app(\Filament\Auth\Notifications\ResetPassword::class, ['token' => $token]);
|
||||
$notification->url = url(route('filament.admin-filament.auth.password-reset.reset', [
|
||||
'token' => $token,
|
||||
'email' => $this->getEmailForPasswordReset(),
|
||||
], false));
|
||||
|
||||
$this->notify($notification);
|
||||
}
|
||||
|
||||
// public function roles()
|
||||
// {
|
||||
// return $this->belongsToMany(\App\Models\Role::class, 'role_user')->withTimestamps();
|
||||
|
|
|
|||
50
app/Notifications/NetGesconResetPasswordNotification.php
Normal file
50
app/Notifications/NetGesconResetPasswordNotification.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Filament\Auth\Notifications\ResetPassword as FilamentResetPassword;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
|
||||
class NetGesconResetPasswordNotification extends FilamentResetPassword
|
||||
{
|
||||
/**
|
||||
* Non implementa ShouldQueue per garantire l'invio immediato e sincrono via SMTP,
|
||||
* eliminando il rischio di blocco nella tabella jobs in assenza di daemon queue:work.
|
||||
*/
|
||||
public function toMail($notifiable): MailMessage
|
||||
{
|
||||
$url = $this->resetUrl($notifiable);
|
||||
$userName = $notifiable->name ? trim((string) $notifiable->name) : 'Utente NetGescon';
|
||||
|
||||
return (new MailMessage)
|
||||
->subject('NetGescon - Reimpostazione della Password')
|
||||
->greeting("Ciao {$userName},")
|
||||
->line('Abbiamo ricevuto una richiesta di reimpostazione della password per il tuo account su NetGescon.')
|
||||
->action('Reimposta Password', $url)
|
||||
->line('Questo link di sicurezza per la reimpostazione della password scadrà tra 60 minuti.')
|
||||
->line('Se non sei stato tu a richiedere la reimpostazione della password, non preoccuparti: puoi ignorare questo messaggio e la tua password attuale rimarrà invariata.')
|
||||
->salutation('Cordiali saluti, lo Staff di NetGescon');
|
||||
}
|
||||
|
||||
protected function resetUrl($notifiable): string
|
||||
{
|
||||
if (! empty($this->url)) {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
try {
|
||||
$panel = Filament::getCurrentOrDefaultPanel();
|
||||
if ($panel && method_exists($panel, 'getResetPasswordUrl')) {
|
||||
return $panel->getResetPasswordUrl($this->token, $notifiable);
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
// fallback al route nominato
|
||||
}
|
||||
|
||||
return url(route('filament.admin-filament.auth.password-reset.reset', [
|
||||
'token' => $this->token,
|
||||
'email' => $notifiable->getEmailForPasswordReset(),
|
||||
], false));
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,11 @@ public function register(): void
|
|||
\App\Http\Responses\FortifyVerifyEmailViewResponse::class
|
||||
);
|
||||
}
|
||||
|
||||
$this->app->bind(
|
||||
\Filament\Auth\Notifications\ResetPassword::class,
|
||||
\App\Notifications\NetGesconResetPasswordNotification::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public function panel(Panel $panel): Panel
|
|||
->login(\App\Filament\Auth\Login::class)
|
||||
->passwordReset()
|
||||
->registration()
|
||||
->profile()
|
||||
->colors([
|
||||
'primary' => Color::Amber,
|
||||
])
|
||||
|
|
|
|||
|
|
@ -1,71 +1,66 @@
|
|||
# CURRENT-205
|
||||
|
||||
TASK_ID: task-tecnorepair-fornitore-sync-workflows
|
||||
TASK_ID: task-email-service-password-reset
|
||||
MACHINE: .205
|
||||
STATO: completato
|
||||
|
||||
## Obiettivo Completato
|
||||
|
||||
1. **Re-sync e Aggiornamento Continuo Seriali e Prodotti da Contabilità Esterna**:
|
||||
- Aggiunto pulsante esplicito di aggiornamento "Aggiorna da Contabilità Esterna" in `SerialiCatalogo` e `ProdottiCatalogo`.
|
||||
- Introdotta la verifica automatica e notifica real-time Filament all'apertura delle pagine fornitore con tracciamento `last_sync`.
|
||||
1. **Attivazione e Diagnostica Servizio Posta SMTP (Google Workspace / Gmail)**:
|
||||
- Configurato e bonificato `.env` con credenziali dedicate Google Workspace:
|
||||
- `MAIL_MAILER=smtp`
|
||||
- `MAIL_HOST=smtp.gmail.com`
|
||||
- `MAIL_PORT=587`
|
||||
- `MAIL_ENCRYPTION=tls`
|
||||
- `MAIL_USERNAME=netgescon@gmail.com`
|
||||
- `MAIL_FROM_ADDRESS=michele@netgescon.it` (NetGescon)
|
||||
- Risolto il blocco delle email in coda: impostato `QUEUE_CONNECTION=sync` ed eliminata la dipendenza da daemon `queue:work` non presenti a sistema.
|
||||
- Svuotata la tabella `jobs` evadendo le notifiche pendenti.
|
||||
|
||||
2. **Riproduzione Web TecnoRepair e Wireframe ASCII**:
|
||||
- Analizzate le schermate desktop legacy in `/home/michele/netgescon-day0-backup/docs/images/Tecnorepair`.
|
||||
- Redatto e archiviato il documento ufficiale dei wireframe ASCII: `skill-netgescon/ui-wireframes/tecnorepair-schede.md`.
|
||||
- Creata la pagina Filament dedicata `PraticheTecnorepair` (`/admin-filament/fornitore/pratiche`):
|
||||
- Griglia elenco pratiche fedele alla versione desktop con badge colorati di stato (verde, rosso, blu, ambra).
|
||||
- Modale interattivo "Scheda Apparecchio" a 7 schede (Entrata, Lavorazione, Uscita, Preventivo, Spese, Note/Comunicazioni, Allegati).
|
||||
- Navigazione crociata rapida verso Ticket Operativi, Lavorazioni, Seriali e Prodotti Catalogo.
|
||||
2. **Notifica di Reimpostazione Password Personalizzata in Italiano (`NetGesconResetPasswordNotification`)**:
|
||||
- Creata la notifica `App\Notifications\NetGesconResetPasswordNotification`:
|
||||
- Invio sincrono immediato (senza code asincrone).
|
||||
- Testo in italiano, grafica formattata, pulsante "Reimposta Password", token univoco e link per copia-incolla con scadenza 60 minuti.
|
||||
- Mittente ufficiale `michele@netgescon.it` (NetGescon).
|
||||
- Registrato il binding in `AppServiceProvider` su `\Filament\Auth\Notifications\ResetPassword`.
|
||||
- Agganciato il metodo `sendPasswordResetNotification()` su `App\Models\User`.
|
||||
|
||||
3. **Integrazione Archivio Access TecnoRepairDB.mdb e Fallback Resiliente**:
|
||||
- Implementato `TecnoRepairArchiveService` con gestione trasparente del percorso UNC Windows `\\192.168.0.36\CServerGO\LunaSoftware_TecnoRepair\Archivi\TecnoRepairDB.mdb` e fallback immediato sul mirror locale Linux (`/home/michele/netgescon-day0-backup/Miki-Bug-workspace/screenshot/Assistenza gestionale/Archivi/TecnoRepairDB.mdb`).
|
||||
- Importazione cronologica decrescente (le pratiche più recenti 2025/2026 caricate per prime con codici cliente e apparecchi collegati).
|
||||
- Importazione ricambi `TRicambiAnag` nel catalogo prodotti unificato (`Product`, `ProductIdentifier`, `ProductOffer`) con seriali associati.
|
||||
3. **Autonomia Cambio Password Utente**:
|
||||
- **Da non autenticato**: abilitato il flusso completo su `/admin-filament/password-reset/request` (link "Hai dimenticato la password?" nella maschera di login).
|
||||
- **Da autenticato**: abilitata la schermata profilo `/admin-filament/profile` tramite `->profile()` in `AdminFilamentPanelProvider`, consentendo il cambio password autonomo direttamente dal menu utente in alto a destra.
|
||||
|
||||
4. **Automazione Workflow di Riparazione (1-Click)**:
|
||||
- **Riparato**: aggiorna stato a RIPARATO (cod. 4), imposta data collaudo, tecnico e archivia la pratica.
|
||||
- **Rottamato / Ricambi**: stato NON CONVENIENTE / ROTTAMATO (cod. 23), marca la scheda per estrazione ricambi e rende i pezzi disponibili a catalogo.
|
||||
- **Reso al Fornitore (RMA)**: stato MANDATO IN GARANZIA AL PRODUTTORE (cod. 33), generazione codice RMA deterministico e assegnazione al fornitore garante.
|
||||
4. **Allineamento Utenze Google Workspace / NetGescon**:
|
||||
- Utenza Workspace `michele@netgescon.it` (User ID 25): attiva con ruoli `super-admin`, `amministratore`, `admin`.
|
||||
- Utenza Google `netgescon@gmail.com` (User ID 35): registrata e attiva con ruolo `super-admin`.
|
||||
- Entrambe le utenze possono richiedere e ricevere la reimpostazione password o accedere in autonomia.
|
||||
|
||||
5. **Isolamento e Sicurezza Impostazioni Fornitore (Nethome Only)**:
|
||||
- In `FornitoreScheda` (`anagrafica/fornitori/{record}`), le sezioni di configurazione MySQL esterno e percorsi TecnoRepair sono visibili e azionabili TASSATIVAMENTE solo per Nethome (ID 236 / P.IVA 10055221005).
|
||||
- Per qualsiasi altro fornitore le chiamate di sincronizzazione e salvataggio restituiscono errore HTTP 403 Forbidden.
|
||||
|
||||
6. **Allineamento Utenti e Ruoli**:
|
||||
- `michele@nethome.it` (ID 33) rigorosamente allineato al solo ruolo `super-admin`.
|
||||
- `nethomestore@gmail.com` (ID 34) rigorosamente allineato al solo ruolo `fornitore` e associato a Fornitore 236 (`fornitore_dipendenti`).
|
||||
5. **Comandi Artisan di Diagnostica e Invio**:
|
||||
- `php artisan netgescon:test-mail {email?}`: invia un'email diagnostica SMTP per testare la connettività Google Workspace.
|
||||
- `php artisan netgescon:send-password-reset {email}`: genera il token crittografato e invia il link di ripristino all'email richiesta.
|
||||
|
||||
## Output del Giro Operativo
|
||||
|
||||
ESITO_205: riuscito
|
||||
TASK_ID: task-tecnorepair-fornitore-sync-workflows
|
||||
TASK_ID: task-email-service-password-reset
|
||||
REPOSITORY: ssh://git@git.netgescon.it:2222/michele/netgescon-day0.git
|
||||
BRANCH: stabilization/205-zero
|
||||
COMMIT: a8435c0
|
||||
COMMIT: 1970594
|
||||
FILE_O_AREE_TOCCATE:
|
||||
- app/Services/Tecnorepair/TecnoRepairArchiveService.php
|
||||
- app/Console/Commands/TecnoRepairImportLegacyArchiveCommand.php
|
||||
- app/Filament/Pages/Fornitore/PraticheTecnorepair.php
|
||||
- resources/views/filament/pages/fornitore/pratiche-tecnorepair.blade.php
|
||||
- skill-netgescon/ui-wireframes/tecnorepair-schede.md
|
||||
- app/Filament/Pages/Gescon/FornitoreScheda.php
|
||||
- resources/views/filament/pages/gescon/fornitore-scheda.blade.php
|
||||
- app/Filament/Pages/Fornitore/SerialiCatalogo.php
|
||||
- resources/views/filament/pages/fornitore/seriali-catalogo.blade.php
|
||||
- app/Filament/Pages/Fornitore/ProdottiCatalogo.php
|
||||
- resources/views/filament/pages/fornitore/prodotti-catalogo.blade.php
|
||||
- resources/views/filament/pages/fornitore/ticket-operativi.blade.php
|
||||
- resources/views/filament/pages/fornitore/lavorazioni-operative.blade.php
|
||||
- tests/Feature/FornitoreTecnorepairAndIntegrationsTest.php
|
||||
- app/Console/Commands/SendPasswordResetEmailCommand.php
|
||||
- app/Console/Commands/TestMailCommand.php
|
||||
- app/Notifications/NetGesconResetPasswordNotification.php
|
||||
- app/Models/User.php
|
||||
- app/Providers/AppServiceProvider.php
|
||||
- app/Providers/Filament/AdminFilamentPanelProvider.php
|
||||
- tests/Feature/PasswordResetAndEmailServiceTest.php
|
||||
- skill-netgescon/control-tower/CURRENT-205.md
|
||||
TEST_ESEGUITI:
|
||||
- ./vendor/bin/pest tests/Feature/FornitoreTecnorepairAndIntegrationsTest.php tests/Feature/FornitoreContabilitaSerialiImportTest.php tests/Feature/StrutturaDatabaseAndStorageTest.php tests/Feature/NominativiAndFeMatchingTest.php tests/Feature/PostaImapWebmailAndProtocolloTest.php tests/Feature/ContabilitaRelazionaleOrdinarieTest.php tests/Feature/BpmBankParserAndImporterTest.php tests/Feature/UnitaGestioneTemporaleTest.php tests/Feature/CatastoHubDbDrivenTest.php tests/Feature/UnitaCondominoInquilinoRoleToggleTest.php tests/Feature/UnitaImmobiliarePageTest.php tests/Feature/BenedettoBonificaIdempotenteTest.php tests/Feature/ControlTowerPollCommandTest.php (41 passed, 270 assertions)
|
||||
- ./vendor/bin/pest tests/Feature/PasswordResetAndEmailServiceTest.php tests/Feature/FornitoreTecnorepairAndIntegrationsTest.php tests/Feature/FornitoreContabilitaSerialiImportTest.php tests/Feature/StrutturaDatabaseAndStorageTest.php tests/Feature/NominativiAndFeMatchingTest.php tests/Feature/PostaImapWebmailAndProtocolloTest.php tests/Feature/ContabilitaRelazionaleOrdinarieTest.php tests/Feature/BpmBankParserAndImporterTest.php tests/Feature/UnitaGestioneTemporaleTest.php tests/Feature/CatastoHubDbDrivenTest.php tests/Feature/UnitaCondominoInquilinoRoleToggleTest.php tests/Feature/UnitaImmobiliarePageTest.php tests/Feature/BenedettoBonificaIdempotenteTest.php tests/Feature/ControlTowerPollCommandTest.php (46 passed, 285 assertions)
|
||||
GATE_STATISTICS:
|
||||
- TECNOREPAIR_MDB_IMPORT: Risoluzione MDB Windows/Linux e import schede 2025/2026.
|
||||
- AUTOMATED_WORKFLOWS: Riparato, Rottamato/Ricambi, Reso RMA operativi.
|
||||
- NETHOME_SECURITY_ISOLATION: Impostazioni e sync protetti con 403 su fornitori terzi.
|
||||
- TEST_SUITE: 41 test Feature passati (270 asserzioni, 100% pass).
|
||||
- SMTP_GMAIL_WORKSPACE: Connessione smtp.gmail.com:587 verificata e funzionante.
|
||||
- PASSWORD_RESET_FLOW: Richiesta da login (/admin-filament/password-reset/request) e da profilo (/admin-filament/profile) operativi.
|
||||
- SYNC_DISPATCH: Notifiche recapitate istantaneamente senza dipendenza da code background.
|
||||
- TEST_SUITE: 46 test Feature passati (285 asserzioni, 100% pass).
|
||||
BLOCCO_DATI: no
|
||||
BLOCCO_CONTRATTO: no
|
||||
RISCHI_APERTI: nessuno
|
||||
|
|
@ -73,6 +68,6 @@ ## Output del Giro Operativo
|
|||
## Prossimo Passo per .200 (Validazione)
|
||||
|
||||
- Eseguire il checkout del branch `stabilization/205-zero`.
|
||||
- Eseguire la suite di test Pest (41 passed, 270 assertions).
|
||||
- Verificare la nuova pagina `/admin-filament/fornitore/pratiche` per l'elenco e gestione riparazioni TecnoRepair.
|
||||
- Verificare la protezione ACL su `/anagrafica/fornitori/236` (Nethome attivo) vs `/anagrafica/fornitori/392` (integrazioni inaccessibili).
|
||||
- Eseguire la suite di test Pest (46 passed, 285 assertions).
|
||||
- Eseguire `php artisan netgescon:test-mail` per verificare la connettività SMTP Google.
|
||||
- Verificare la ricezione del link di reset e la modifica autonoma della password.
|
||||
|
|
|
|||
70
tests/Feature/PasswordResetAndEmailServiceTest.php
Normal file
70
tests/Feature/PasswordResetAndEmailServiceTest.php
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
use App\Notifications\NetGesconResetPasswordNotification;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
beforeEach(function () {
|
||||
Role::firstOrCreate(['name' => 'super-admin', 'guard_name' => 'web']);
|
||||
Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']);
|
||||
});
|
||||
|
||||
test('it verifies mail service configuration defaults for netgescon', function () {
|
||||
expect(config('mail.mailers.smtp.transport'))->toBe('smtp')
|
||||
->and(config('mail.mailers.smtp.host'))->toBe('smtp.gmail.com')
|
||||
->and(config('mail.from.address'))->toBe('michele@netgescon.it')
|
||||
->and(config('mail.from.name'))->toBe('NetGescon');
|
||||
});
|
||||
|
||||
test('it formats NetGescon password reset notification with Italian text and security links', function () {
|
||||
$user = User::factory()->create([
|
||||
'name' => 'Michele Test',
|
||||
'email' => 'michele.test@netgescon.it',
|
||||
]);
|
||||
$user->assignRole('super-admin');
|
||||
|
||||
$notification = new NetGesconResetPasswordNotification('test-token-123');
|
||||
$notification->url = 'http://192.168.0.205:8000/admin-filament/password-reset/reset?token=test-token-123';
|
||||
|
||||
$mail = $notification->toMail($user);
|
||||
|
||||
expect($mail->subject)->toBe('NetGescon - Reimpostazione della Password')
|
||||
->and($mail->greeting)->toContain('Michele Test')
|
||||
->and($mail->actionText)->toBe('Reimposta Password')
|
||||
->and($mail->actionUrl)->toBe('http://192.168.0.205:8000/admin-filament/password-reset/reset?token=test-token-123')
|
||||
->and(collect($mail->introLines)->join(' '))->toContain('NetGescon')
|
||||
->and(collect($mail->outroLines)->join(' '))->toContain('60 minuti');
|
||||
});
|
||||
|
||||
test('it sends password reset email via artisan command for registered user', function () {
|
||||
Notification::fake();
|
||||
|
||||
$user = User::factory()->create([
|
||||
'name' => 'Mario Rossi',
|
||||
'email' => 'mario.rossi@netgescon.it',
|
||||
]);
|
||||
$user->assignRole('admin');
|
||||
|
||||
$exitCode = Artisan::call('netgescon:send-password-reset', ['email' => 'mario.rossi@netgescon.it']);
|
||||
expect($exitCode)->toBe(0);
|
||||
|
||||
Notification::assertSentTo($user, NetGesconResetPasswordNotification::class);
|
||||
});
|
||||
|
||||
test('it fails artisan command gracefully when user does not exist', function () {
|
||||
$exitCode = Artisan::call('netgescon:send-password-reset', ['email' => 'nonexistent@netgescon.it']);
|
||||
expect($exitCode)->toBe(1);
|
||||
});
|
||||
|
||||
test('it mounts Filament password reset request page and profile page routes', function () {
|
||||
$requestResponse = $this->get('/admin-filament/password-reset/request');
|
||||
$requestResponse->assertStatus(200);
|
||||
|
||||
$profileRoute = route('filament.admin-filament.auth.profile');
|
||||
expect($profileRoute)->toContain('/admin-filament/profile');
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user