user:make_abo_order nimmt nur Abos mit next_date = heute; faellt ein Lauf aus, bleibt ein Abo stillschweigend liegen (Abo 39: Termin 25.03.2026). abo:check-overdue meldet taeglich um 05:30 alle aktiven Abos mit Status okay und verstrichenem Termin per Mail an mivita (Link ins Admin-Abo) und ins abo_order-Log. Es wird bewusst nichts nachgebucht; --no-mail nur fuer die Ausgabe. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
76 lines
2.5 KiB
PHP
76 lines
2.5 KiB
PHP
<?php
|
|
|
|
use App\Mail\AboOverdueAlertMail;
|
|
use App\Models\UserAbo;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Tests\TestCase;
|
|
|
|
uses(TestCase::class, RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
Carbon::setTestNow(Carbon::parse('2026-09-23 05:30:00'));
|
|
Mail::fake();
|
|
});
|
|
|
|
afterEach(fn () => Carbon::setTestNow());
|
|
|
|
function overdueAbo(string $nextDate, int $status = 2, bool $active = true): UserAbo
|
|
{
|
|
return UserAbo::create([
|
|
'user_id' => null,
|
|
'member_id' => 1,
|
|
'shopping_user_id' => 0,
|
|
'is_for' => 'ot',
|
|
'email' => 'abo-'.uniqid('', true).'@example.com',
|
|
'payone_userid' => 1,
|
|
'clearingtype' => 'cc',
|
|
'active' => $active,
|
|
'status' => $status,
|
|
'abo_interval' => (int) Carbon::parse($nextDate)->day,
|
|
'start_date' => '2026-01-01',
|
|
'next_date' => $nextDate,
|
|
]);
|
|
}
|
|
|
|
it('meldet laufende Abos mit verstrichenem Termin und bucht nichts nach', function () {
|
|
$stuck = overdueAbo('2026-03-25');
|
|
overdueAbo('2026-09-23'); // heute faellig: laeuft regulaer
|
|
overdueAbo('2026-10-05'); // Zukunft
|
|
overdueAbo('2026-08-10', status: 3); // Zahlung fehlgeschlagen: eigener Zustand
|
|
overdueAbo('2026-08-10', active: false); // inaktiv
|
|
|
|
$this->artisan('abo:check-overdue')
|
|
->expectsOutputToContain('Überfällige Abos: 1')
|
|
->assertSuccessful();
|
|
|
|
Mail::assertSent(AboOverdueAlertMail::class, function (AboOverdueAlertMail $mail) use ($stuck) {
|
|
$html = $mail->render();
|
|
|
|
return $mail->hasTo(config('app.default_mail'))
|
|
&& count($mail->overdueAbos) === 1
|
|
&& str_contains($html, '#'.$stuck->id)
|
|
&& str_contains($html, '25.03.2026')
|
|
&& str_contains($html, '/admin/abos/detail/'.$stuck->id);
|
|
});
|
|
|
|
expect(Carbon::parse($stuck->fresh()->getRawOriginal('next_date'))->toDateString())->toBe('2026-03-25')
|
|
->and($stuck->user_abo_orders()->count())->toBe(0);
|
|
});
|
|
|
|
it('schickt ohne ueberfaellige Abos keine Mail', function () {
|
|
overdueAbo('2026-10-05');
|
|
|
|
$this->artisan('abo:check-overdue')->expectsOutputToContain('Keine überfälligen Abos.')->assertSuccessful();
|
|
|
|
Mail::assertNothingSent();
|
|
});
|
|
|
|
it('schickt mit --no-mail nur die Ausgabe', function () {
|
|
overdueAbo('2026-09-01');
|
|
|
|
$this->artisan('abo:check-overdue', ['--no-mail' => true])->assertSuccessful();
|
|
|
|
Mail::assertNothingSent();
|
|
});
|