'CluPilot Cloud e.U.', 'address' => 'Dreherstraße 66/1/8', 'postcode' => '1110', 'city' => 'Wien', 'vat_id' => 'ATU00000000', ]); $customer = Customer::factory()->create(['name' => 'Muster GmbH']); $orders = collect([Order::factory()->create([ 'customer_id' => $customer->id, 'amount_cents' => 1900, 'currency' => 'EUR', 'status' => 'paid', ])]); return app(IssueInvoice::class)->forOrders($customer, $orders); } it('reiht jede Mail in die Schlange ihrer Spur ein', function () { Queue::fake(); Mail::to('kunde@example.test')->queue(new InvoiceMail(invoiceForTest(), 'Muster')); Queue::assertPushedOn(MailLane::CALM, Illuminate\Mail\SendQueuedMailable::class); }); it('reiht eine Direkt-Mail in die Direkt-Spur ein', function () { Queue::fake(); $user = User::factory()->create(); Mail::to('kunde@example.test')->queue(new ResetPasswordMail($user, 'https://example.test/reset', 60)); Queue::assertPushedOn(MailLane::DIRECT, Illuminate\Mail\SendQueuedMailable::class); }); it('folgt einer verschobenen Zuordnung', function () { Queue::fake(); MailLane::assign(InvoiceMail::class, MailLane::URGENT); Mail::to('kunde@example.test')->queue(new InvoiceMail(invoiceForTest(), 'Muster')); Queue::assertPushedOn(MailLane::URGENT, Illuminate\Mail\SendQueuedMailable::class); }); /** * Rekursiv statt `glob('Mail/*.php')`: `app/Mail` hat mit `Concerns/` und * `Transport/` schon zwei Unterordner und wird eher mehr als weniger. Eine * fünfzehnte Mailklasse in einem Unterordner sähe der alte `glob()`-Aufruf * nie — der Wächter schwiege genau in dem Moment, in dem er gebraucht wird. * * Eingeschränkt auf echte Mailables (Unterklassen von * `Illuminate\Mail\Mailable`) statt auf „liegt irgendwo unter app/Mail": * ein Trait wie `RidesALane` selbst, oder eine künftige Basisklasse, ist * keine versendbare Mail, braucht keine Spur und soll den Test nicht rot * machen, nur weil sie im selben Ordner liegt. */ it('lässt keine Mailklasse ohne Spur', function () { $missing = collect(File::allFiles(app_path('Mail'))) ->map(fn ($file) => 'App\\Mail\\'.str_replace( [DIRECTORY_SEPARATOR, '.php'], ['\\', ''], $file->getRelativePathname() )) ->filter(fn (string $class) => is_subclass_of($class, Mailable::class)) ->reject(fn (string $class) => in_array(RidesALane::class, class_uses_recursive($class), true)) ->values() ->all(); expect($missing)->toBe([]); });