set('admin_access.secrets_key', 'base64:'.base64_encode(random_bytes(32))); Settings::set('mail.host', 'mail.example.test'); Settings::set('mail.port', 587); Settings::set('mail.encryption', 'tls'); }); it('registers a mailer per purpose without touching the database at boot', function () { // The five entries exist as plain config — no query has run to build them. foreach (MailPurpose::ALL as $purpose) { expect(config('mail.mailers.cp_'.$purpose)) ->toMatchArray(['transport' => 'mailbox', 'purpose' => $purpose]); } }); it('builds the transport from the mailbox that is current at send time', function () { Mailbox::factory()->create(['key' => 'support', 'address' => 'support@clupilot.com']); Settings::set(MailPurpose::settingKey(MailPurpose::SUPPORT), 'support'); config()->set('mail.default', 'smtp'); // delivery on, as on live $transport = Mail::mailer('cp_support')->getSymfonyTransport(); expect($transport)->toBeInstanceOf(MailboxTransport::class) ->and((string) $transport)->toContain('support@clupilot.com'); }); it('logs instead of delivering while MAIL_MAILER is log', function () { Mailbox::factory()->create(['key' => 'support', 'address' => 'support@clupilot.com']); Settings::set(MailPurpose::settingKey(MailPurpose::SUPPORT), 'support'); config()->set('mail.default', 'log'); $transport = Mail::mailer('cp_support')->getSymfonyTransport(); // Still our transport — but it hands the message to the log, so a seeder // run cannot mail a real customer from a development machine. expect((string) $transport)->toContain('log'); }); /* | __toString() and send() decide "log or SMTP" through two SEPARATE code | paths (describe() vs delegate()). The test above only exercises the first — | it would keep passing even if delegate() lost its own guard and sent every | purpose-mailer through real SMTP regardless of MAIL_MAILER. Reach into the | method that actually sends, so that regression cannot hide behind a passing | __toString() assertion. No real socket is opened either way: EsmtpTransport | connects lazily on send(), never in its constructor. */ it('actually delegates to the log transport, not SMTP, while MAIL_MAILER is log', function () { Mailbox::factory()->create(['key' => 'support', 'address' => 'support@clupilot.com']); Settings::set(MailPurpose::settingKey(MailPurpose::SUPPORT), 'support'); config()->set('mail.default', 'log'); $transport = Mail::mailer('cp_support')->getSymfonyTransport(); $delegate = Closure::bind(fn () => $this->delegate(), $transport, MailboxTransport::class)(); expect($delegate)->toBeInstanceOf(LogTransport::class); }); it('delegates to a real SMTP transport once MAIL_MAILER is no longer log', function () { Mailbox::factory()->create(['key' => 'support', 'address' => 'support@clupilot.com']); Settings::set(MailPurpose::settingKey(MailPurpose::SUPPORT), 'support'); config()->set('mail.default', 'smtp'); $transport = Mail::mailer('cp_support')->getSymfonyTransport(); $delegate = Closure::bind(fn () => $this->delegate(), $transport, MailboxTransport::class)(); expect($delegate)->toBeInstanceOf(EsmtpTransport::class); });