98 lines
3.7 KiB
PHP
98 lines
3.7 KiB
PHP
<?php
|
|
|
|
use App\Mail\Transport\MailboxTransport;
|
|
use App\Models\Mailbox;
|
|
use App\Services\Mail\MailPurpose;
|
|
use App\Support\MailDelivery;
|
|
use App\Support\Readiness\DeliveryChecks;
|
|
use App\Support\Settings;
|
|
|
|
/**
|
|
* Warum die „Passwort vergessen"-Mail nicht ankam, obwohl die Zustellung
|
|
* eingeschaltet war.
|
|
*
|
|
* Die Kette, im Code nachgelesen:
|
|
*
|
|
* User::sendPasswordResetNotification → ResetPasswordMail (ShouldQueue)
|
|
* → Warteschlange → MailboxTransport('system')
|
|
* → MailboxResolver::for('system') liefert null
|
|
* → delegate() WIRFT „No configured mailbox for mail purpose [system]"
|
|
* → der Auftrag scheitert und landet in `failed_jobs`
|
|
*
|
|
* Und niemand erfährt davon: `RecordSentMail` hört auf `MessageSent`, also auf
|
|
* das, was den Server VERLASSEN hat — ein Wurf davor hinterlässt keine Zeile im
|
|
* Postausgang. Das Portal hat dem Kunden längst „sehen Sie in Ihr Postfach"
|
|
* gesagt.
|
|
*
|
|
* Die Bereitschaftsseite hätte das melden müssen und tat es nicht: sie fragte
|
|
* `Mailbox::query()->exists()` — ob IRGENDEIN Postfach angelegt ist. Das ist
|
|
* nicht die Frage, an der das Senden hängt.
|
|
*/
|
|
beforeEach(function () {
|
|
Settings::set(MailDelivery::SETTING, MailDelivery::DELIVERING);
|
|
Mailbox::query()->delete();
|
|
Settings::forget(MailPurpose::settingKey(MailPurpose::SYSTEM));
|
|
});
|
|
|
|
function systemCheckSatisfied(): bool
|
|
{
|
|
foreach (DeliveryChecks::all() as $check) {
|
|
if ($check->key === 'delivery.mailbox') {
|
|
return $check->satisfied;
|
|
}
|
|
}
|
|
|
|
throw new RuntimeException('delivery.mailbox check is gone');
|
|
}
|
|
|
|
it('is not satisfied by a mailbox that no purpose points at', function () {
|
|
// Genau der gemeldete Zustand: ein Postfach ist angelegt, die Seite ist
|
|
// gruen, und jede Systemmail stirbt trotzdem in der Warteschlange.
|
|
Mailbox::factory()->create(['key' => 'irgendwas', 'active' => true]);
|
|
|
|
expect(systemCheckSatisfied())->toBeFalse();
|
|
});
|
|
|
|
it('is not satisfied when the system purpose points at an inactive mailbox', function () {
|
|
$box = Mailbox::factory()->create(['key' => 'system', 'active' => false]);
|
|
Settings::set(MailPurpose::settingKey(MailPurpose::SYSTEM), $box->key);
|
|
|
|
expect(systemCheckSatisfied())->toBeFalse();
|
|
});
|
|
|
|
it('is not satisfied when the mailbox authenticates but carries no password', function () {
|
|
$box = Mailbox::factory()->create([
|
|
'key' => 'system', 'active' => true, 'authenticates' => true, 'password' => null,
|
|
]);
|
|
Settings::set(MailPurpose::settingKey(MailPurpose::SYSTEM), $box->key);
|
|
|
|
expect(systemCheckSatisfied())->toBeFalse();
|
|
});
|
|
|
|
it('is satisfied by a mailbox the transport would actually use', function () {
|
|
$box = Mailbox::factory()->create([
|
|
'key' => 'system', 'active' => true, 'authenticates' => false,
|
|
]);
|
|
Settings::set(MailPurpose::settingKey(MailPurpose::SYSTEM), $box->key);
|
|
|
|
expect(systemCheckSatisfied())->toBeTrue();
|
|
});
|
|
|
|
it('agrees with the transport, which is the whole point', function () {
|
|
// Zwei Stellen, die dieselbe Frage verschieden beantworten, sind der Weg,
|
|
// auf dem sie auseinanderlaufen — dieses Projekt hat das mehrfach bezahlt.
|
|
// Der Test haelt die zwei aneinander, nicht jede an eine eigene Meinung.
|
|
Mailbox::factory()->create(['key' => 'irgendwas', 'active' => true]);
|
|
|
|
expect(systemCheckSatisfied())->toBeFalse()
|
|
->and((string) new MailboxTransport(MailPurpose::SYSTEM))->toContain('unconfigured');
|
|
|
|
$box = Mailbox::factory()->create([
|
|
'key' => 'system', 'active' => true, 'authenticates' => false,
|
|
]);
|
|
Settings::set(MailPurpose::settingKey(MailPurpose::SYSTEM), $box->key);
|
|
|
|
expect(systemCheckSatisfied())->toBeTrue()
|
|
->and((string) new MailboxTransport(MailPurpose::SYSTEM))->not->toContain('unconfigured');
|
|
});
|