test(MailSettings::class) ->set('mailConfig.fromAddress', 'wsparcie@firma.pl') ->set('mailConfig.fromName', 'Zespół Wsparcia') ->set('mailConfig.smtpEnabled', true) ->set('mailConfig.smtpHost', 'smtp.firma.pl') ->set('mailConfig.smtpPort', '587') ->set('mailConfig.smtpUsername', 'no-reply') ->set('mailConfig.smtpPassword', 'sekret123') ->set('mailConfig.smtpEncryption', 'tls') ->call('saveMailConfig') ->assertOk(); expect(Settings::get('mail_from_address'))->toBe('wsparcie@firma.pl') ->and(Settings::get('mail_from_name'))->toBe('Zespół Wsparcia') ->and(Settings::bool('mail_smtp_enabled'))->toBeTrue() ->and(Settings::get('mail_smtp_host'))->toBe('smtp.firma.pl') ->and(Settings::get('mail_smtp_password'))->toBe('sekret123'); // Saving again with a blank password field must not wipe the stored one. Livewire::actingAs($admin)->test(MailSettings::class) ->set('mailConfig.smtpHost', 'smtp.firma.pl') ->set('mailConfig.smtpPassword', '') ->call('saveMailConfig') ->assertOk(); expect(Settings::get('mail_smtp_password'))->toBe('sekret123'); }); test('the SMTP test button reports an error without a host/from address, and success once mail is faked and both are set', function () { Mail::fake(); $admin = adminUser(); Livewire::actingAs($admin)->test(MailSettings::class) ->call('testMailConnection') ->assertSet('mailTestResult', 'error'); // Mail::fake()'s raw() is a no-op that never throws, so a valid config // reports success — this exercises the same config-override/restore path // real sends use, without needing a reachable SMTP server in tests. Livewire::actingAs($admin)->test(MailSettings::class) ->set('mailConfig.fromAddress', 'wsparcie@firma.pl') ->set('mailConfig.smtpHost', 'smtp.firma.pl') ->call('testMailConnection') ->assertSet('mailTestResult', 'ok'); }); test('the configured footer is appended to every rendered notification', function () { Settings::set('email_footer', 'Stopka testowa.'); $template = EmailTemplate::query()->create([ 'key' => 'tpl-footer-test', 'name' => 'x', 'trigger_label' => 'x', 'subject' => 'S', 'body' => 'Treść wiadomości.', ]); $ticket = makeTicket(); $mail = (new TicketNotification($ticket, $template->id))->toMail((object) ['routes' => ['mail' => $ticket->email]]); expect($mail->viewData['html'])->toContain('Treść wiadomości.') ->and($mail->viewData['html'])->toContain('Stopka testowa.'); }); test('an empty footer setting adds nothing extra to the notification', function () { Settings::set('email_footer', ''); $template = EmailTemplate::query()->create([ 'key' => 'tpl-footer-test-2', 'name' => 'x', 'trigger_label' => 'x', 'subject' => 'S', 'body' => 'Treść wiadomości.', ]); $ticket = makeTicket(); $mail = (new TicketNotification($ticket, $template->id))->toMail((object) ['routes' => ['mail' => $ticket->email]]); expect($mail->viewData['html'])->toContain('Treść wiadomości.'); }); test('AppServiceProvider overrides the mail config from settings only when SMTP is enabled', function () { Settings::set('mail_smtp_enabled', '0'); Settings::set('mail_smtp_host', 'smtp.disabled.example'); (new AppServiceProvider(app()))->boot(); expect(config('mail.default'))->not->toBe('smtp'); Settings::set('mail_smtp_enabled', '1'); Settings::set('mail_smtp_host', 'smtp.enabled.example'); Settings::set('mail_smtp_port', '2525'); (new AppServiceProvider(app()))->boot(); expect(config('mail.default'))->toBe('smtp') ->and(config('mail.mailers.smtp.host'))->toBe('smtp.enabled.example') ->and(config('mail.mailers.smtp.port'))->toBe(2525); }); test('AppServiceProvider always applies the from-address override regardless of SMTP toggle', function () { Settings::set('mail_smtp_enabled', '0'); Settings::set('mail_from_address', 'wsparcie@firma.pl'); Settings::set('mail_from_name', 'Wsparcie'); (new AppServiceProvider(app()))->boot(); expect(config('mail.from.address'))->toBe('wsparcie@firma.pl') ->and(config('mail.from.name'))->toBe('Wsparcie'); }); test('regression: the mail override still applies for a console command other than migrate (e.g. schedule:run/tinker)', function () { // Reproduces the real production bug: settingsTableUsable() used to // blanket-skip for *any* console command, which meant scheduled // commands (emails:fetch-imap, tickets:check-sla-breaches) always sent // mail via the .env "log" mailer instead of the configured SMTP server, // since AppServiceProvider::boot() runs on every process including // console ones. Only the migrate family should still be excluded. $originalArgv = $_SERVER['argv'] ?? null; Settings::set('mail_smtp_enabled', '1'); Settings::set('mail_smtp_host', 'smtp.enabled.example'); try { $_SERVER['argv'] = ['artisan', 'emails:fetch-imap']; (new AppServiceProvider(app()))->boot(); expect(config('mail.default'))->toBe('smtp'); Config::set('mail.default', 'log'); $_SERVER['argv'] = ['artisan', 'migrate']; (new AppServiceProvider(app()))->boot(); expect(config('mail.default'))->not->toBe('smtp'); } finally { $_SERVER['argv'] = $originalArgv; } });