Deploy Ladill Transfer / deploy (push) Successful in 1m0s
Send grace-entered and countdown emails to owners alongside recipient grace milestones so unpaid transfers get clear wallet top-up reminders before deletion. Co-authored-by: Cursor <cursoragent@cursor.com>
117 lines
3.7 KiB
PHP
117 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Transfer;
|
|
use App\Models\User;
|
|
use App\Notifications\TransferOwnerGraceNotification;
|
|
use App\Services\Transfer\TransferBillingService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Illuminate\Support\Str;
|
|
use Tests\Concerns\FakesTransferBilling;
|
|
use Tests\TestCase;
|
|
|
|
class TransferBillingTest extends TestCase
|
|
{
|
|
use FakesTransferBilling;
|
|
use RefreshDatabase;
|
|
|
|
public function test_failed_renewal_enters_grace_period(): void
|
|
{
|
|
Notification::fake();
|
|
|
|
$user = User::create([
|
|
'public_id' => (string) Str::uuid(),
|
|
'name' => 'Grace User',
|
|
'email' => 'grace+'.uniqid().'@example.com',
|
|
]);
|
|
|
|
$transfer = Transfer::create([
|
|
'user_id' => $user->id,
|
|
'title' => 'Due soon',
|
|
'retention_days' => 30,
|
|
'paid_until' => now()->subMinute(),
|
|
'status' => Transfer::STATUS_ACTIVE,
|
|
'storage_bytes' => 1024 * 1024 * 1024,
|
|
]);
|
|
|
|
$base = rtrim((string) config('billing.api_url'), '/');
|
|
Http::fake([
|
|
$base.'/can-afford*' => Http::response(['affordable' => false]),
|
|
]);
|
|
|
|
$result = app(TransferBillingService::class)->processDueRenewals();
|
|
|
|
$transfer->refresh();
|
|
$this->assertSame(1, $result['graced']);
|
|
$this->assertSame(Transfer::STATUS_GRACE, $transfer->status);
|
|
$this->assertNotNull($transfer->grace_ends_at);
|
|
$this->assertTrue($transfer->grace_ends_at->isFuture());
|
|
$this->assertTrue($transfer->isAccessible());
|
|
|
|
Notification::assertSentTo($user, TransferOwnerGraceNotification::class);
|
|
}
|
|
|
|
public function test_transfer_past_grace_period_is_deleted(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => (string) Str::uuid(),
|
|
'name' => 'Delete User',
|
|
'email' => 'delete+'.uniqid().'@example.com',
|
|
]);
|
|
|
|
Transfer::create([
|
|
'user_id' => $user->id,
|
|
'title' => 'Expired',
|
|
'retention_days' => 30,
|
|
'paid_until' => now()->subDays(20),
|
|
'grace_ends_at' => now()->subMinute(),
|
|
'status' => Transfer::STATUS_GRACE,
|
|
'storage_bytes' => 1024,
|
|
]);
|
|
|
|
$base = rtrim((string) config('billing.api_url'), '/');
|
|
Http::fake([
|
|
$base.'/can-afford*' => Http::response(['affordable' => false]),
|
|
]);
|
|
|
|
$result = app(TransferBillingService::class)->processDueRenewals();
|
|
|
|
$this->assertSame(1, $result['deleted']);
|
|
$this->assertDatabaseHas('transfers', [
|
|
'title' => 'Expired',
|
|
'status' => Transfer::STATUS_DELETED,
|
|
]);
|
|
}
|
|
|
|
public function test_successful_renewal_extends_paid_until(): void
|
|
{
|
|
$user = User::create([
|
|
'public_id' => (string) Str::uuid(),
|
|
'name' => 'Renew User',
|
|
'email' => 'renew+'.uniqid().'@example.com',
|
|
]);
|
|
|
|
$transfer = Transfer::create([
|
|
'user_id' => $user->id,
|
|
'title' => 'Renew me',
|
|
'retention_days' => 30,
|
|
'paid_until' => now()->subMinute(),
|
|
'status' => Transfer::STATUS_ACTIVE,
|
|
'storage_bytes' => 1024 * 1024 * 1024,
|
|
]);
|
|
|
|
$this->fakeTransferBillingApi();
|
|
|
|
$result = app(TransferBillingService::class)->processDueRenewals();
|
|
|
|
$transfer->refresh();
|
|
$this->assertSame(1, $result['renewed']);
|
|
$this->assertSame(Transfer::STATUS_ACTIVE, $transfer->status);
|
|
$this->assertTrue($transfer->paid_until->isFuture());
|
|
$this->assertNull($transfer->grace_ends_at);
|
|
}
|
|
}
|