181 lines
7.4 KiB
PHP
181 lines
7.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\AI\AiUsageLog;
|
|
use App\Models\AiHealingLog;
|
|
use App\Models\MobileErrorLog;
|
|
use App\Models\MobileSyncLog;
|
|
use App\Models\Notification;
|
|
use App\Models\OtpCode;
|
|
use App\Models\PasswordHistory;
|
|
use App\Models\User;
|
|
use App\Models\UserTrustedDevice;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
// ── OtpCode ───────────────────────────────────────────────────────────────────
|
|
|
|
test('OtpCode prunable selects only expired records', function () {
|
|
OtpCode::create(['identifier' => 'a@a.com', 'code' => '111111', 'expires_at' => now()->subMinute()]);
|
|
OtpCode::create(['identifier' => 'b@b.com', 'code' => '222222', 'expires_at' => now()->addHour()]);
|
|
|
|
$prunableIds = (new OtpCode)->prunable()->pluck('id');
|
|
|
|
expect($prunableIds)->toHaveCount(1);
|
|
});
|
|
|
|
test('OtpCode prunable returns a Builder instance', function () {
|
|
expect((new OtpCode)->prunable())->toBeInstanceOf(Builder::class);
|
|
});
|
|
|
|
// ── UserTrustedDevice ─────────────────────────────────────────────────────────
|
|
|
|
test('UserTrustedDevice prunable selects expired devices only', function () {
|
|
$user = User::factory()->create();
|
|
|
|
UserTrustedDevice::create([
|
|
'user_id' => $user->id,
|
|
'device_id' => 'old-device',
|
|
'token' => 'tok1',
|
|
'expires_at' => now()->subDay(),
|
|
]);
|
|
UserTrustedDevice::create([
|
|
'user_id' => $user->id,
|
|
'device_id' => 'fresh-device',
|
|
'token' => 'tok2',
|
|
'expires_at' => now()->addDays(30),
|
|
]);
|
|
|
|
$ids = (new UserTrustedDevice)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toHaveCount(1);
|
|
});
|
|
|
|
test('UserTrustedDevice prunable returns a Builder instance', function () {
|
|
expect((new UserTrustedDevice)->prunable())->toBeInstanceOf(Builder::class);
|
|
});
|
|
|
|
// ── PasswordHistory ───────────────────────────────────────────────────────────
|
|
|
|
test('PasswordHistory prunable selects records older than 365 days', function () {
|
|
$user = User::factory()->create();
|
|
|
|
\DB::table('password_histories')->insert([
|
|
['user_id' => $user->id, 'password' => 'h1', 'created_at' => now()->subDays(400), 'updated_at' => now()],
|
|
['user_id' => $user->id, 'password' => 'h2', 'created_at' => now()->subDays(100), 'updated_at' => now()],
|
|
]);
|
|
|
|
$ids = (new PasswordHistory)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toHaveCount(1);
|
|
});
|
|
|
|
test('PasswordHistory prunable returns a Builder instance', function () {
|
|
expect((new PasswordHistory)->prunable())->toBeInstanceOf(Builder::class);
|
|
});
|
|
|
|
// ── MobileSyncLog ─────────────────────────────────────────────────────────────
|
|
|
|
test('MobileSyncLog prunable selects records older than 30 days', function () {
|
|
\DB::table('mobile_sync_logs')->insert([
|
|
['synced_at' => now()->subDays(35)],
|
|
['synced_at' => now()->subDays(10)],
|
|
]);
|
|
|
|
$ids = (new MobileSyncLog)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toHaveCount(1);
|
|
});
|
|
|
|
test('MobileSyncLog prunable returns a Builder instance', function () {
|
|
expect((new MobileSyncLog)->prunable())->toBeInstanceOf(Builder::class);
|
|
});
|
|
|
|
// ── MobileErrorLog ────────────────────────────────────────────────────────────
|
|
|
|
test('MobileErrorLog prunable selects records older than 90 days', function () {
|
|
\DB::table('mobile_error_logs')->insert([
|
|
['message' => 'old error', 'occurred_at' => now()->subDays(100)],
|
|
['message' => 'new error', 'occurred_at' => now()->subDays(5)],
|
|
]);
|
|
|
|
$ids = (new MobileErrorLog)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toHaveCount(1);
|
|
});
|
|
|
|
test('MobileErrorLog prunable returns a Builder instance', function () {
|
|
expect((new MobileErrorLog)->prunable())->toBeInstanceOf(Builder::class);
|
|
});
|
|
|
|
// ── Notification (system_notifications) ──────────────────────────────────────
|
|
|
|
test('Notification prunable selects records older than 30 days', function () {
|
|
\DB::table('system_notifications')->insert([
|
|
['title' => 'old', 'message' => 'x', 'recipient' => 'all', 'type' => 'info', 'created_at' => now()->subDays(40), 'updated_at' => now()],
|
|
['title' => 'new', 'message' => 'y', 'recipient' => 'all', 'type' => 'info', 'created_at' => now()->subDays(5), 'updated_at' => now()],
|
|
]);
|
|
|
|
$ids = (new Notification)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toHaveCount(1);
|
|
});
|
|
|
|
test('Notification prunable returns a Builder instance', function () {
|
|
expect((new Notification)->prunable())->toBeInstanceOf(Builder::class);
|
|
});
|
|
|
|
// ── AiHealingLog ──────────────────────────────────────────────────────────────
|
|
|
|
test('AiHealingLog prunable selects records older than 90 days', function () {
|
|
\DB::table('ai_healing_logs')->insert([
|
|
['error_message' => 'old', 'created_at' => now()->subDays(100), 'updated_at' => now()],
|
|
['error_message' => 'new', 'created_at' => now()->subDays(10), 'updated_at' => now()],
|
|
]);
|
|
|
|
$ids = (new AiHealingLog)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toHaveCount(1);
|
|
});
|
|
|
|
test('AiHealingLog prunable returns a Builder instance', function () {
|
|
expect((new AiHealingLog)->prunable())->toBeInstanceOf(Builder::class);
|
|
});
|
|
|
|
// ── AiUsageLog ────────────────────────────────────────────────────────────────
|
|
|
|
test('AiUsageLog prunable selects records older than 3 months', function () {
|
|
\DB::table('ai_usage_logs')->insert([
|
|
['provider' => 'openai', 'model' => 'gpt-4', 'status' => 'success', 'created_at' => now()->subMonths(4), 'updated_at' => now()],
|
|
['provider' => 'openai', 'model' => 'gpt-4', 'status' => 'success', 'created_at' => now()->subWeek(), 'updated_at' => now()],
|
|
]);
|
|
|
|
$ids = (new AiUsageLog)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toHaveCount(1);
|
|
});
|
|
|
|
// ── Edge cases ────────────────────────────────────────────────────────────────
|
|
|
|
test('OtpCode prunable returns empty when all codes are still valid', function () {
|
|
OtpCode::create(['identifier' => 'c@c.com', 'code' => '333333', 'expires_at' => now()->addHour()]);
|
|
|
|
$ids = (new OtpCode)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toBeEmpty();
|
|
});
|
|
|
|
test('UserTrustedDevice prunable returns empty when no devices are expired', function () {
|
|
$user = User::factory()->create();
|
|
UserTrustedDevice::create([
|
|
'user_id' => $user->id,
|
|
'device_id' => 'good-device',
|
|
'token' => 'tok3',
|
|
'expires_at' => now()->addDays(7),
|
|
]);
|
|
|
|
$ids = (new UserTrustedDevice)->prunable()->pluck('id');
|
|
|
|
expect($ids)->toBeEmpty();
|
|
});
|