2026-03-09 17:32:55 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Tests\Feature\Jobs;
|
|
|
|
|
|
|
|
|
|
use App\Enums\NotificationSeverityEnum;
|
|
|
|
|
use App\Enums\NotificationTypeEnum;
|
|
|
|
|
use App\Jobs\CheckFeedStalenessJob;
|
|
|
|
|
use App\Models\Feed;
|
|
|
|
|
use App\Models\Notification;
|
|
|
|
|
use App\Models\Setting;
|
2026-03-18 20:01:25 +01:00
|
|
|
use App\Services\Notification\NotificationService;
|
2026-03-09 17:32:55 +01:00
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
|
use Tests\TestCase;
|
|
|
|
|
|
|
|
|
|
class CheckFeedStalenessJobTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
use RefreshDatabase;
|
|
|
|
|
|
|
|
|
|
public function test_stale_feed_creates_notification(): void
|
|
|
|
|
{
|
|
|
|
|
$feed = Feed::factory()->create([
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'last_fetched_at' => now()->subHours(50),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->dispatch();
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('notifications', [
|
|
|
|
|
'type' => NotificationTypeEnum::FEED_STALE->value,
|
|
|
|
|
'severity' => NotificationSeverityEnum::WARNING->value,
|
|
|
|
|
'notifiable_type' => $feed->getMorphClass(),
|
|
|
|
|
'notifiable_id' => $feed->id,
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_fresh_feed_does_not_create_notification(): void
|
|
|
|
|
{
|
|
|
|
|
Feed::factory()->create([
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'last_fetched_at' => now()->subHours(10),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->dispatch();
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseCount('notifications', 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_inactive_feed_does_not_create_notification(): void
|
|
|
|
|
{
|
|
|
|
|
Feed::factory()->create([
|
|
|
|
|
'is_active' => false,
|
|
|
|
|
'last_fetched_at' => now()->subHours(100),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->dispatch();
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseCount('notifications', 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_does_not_create_duplicate_notification_when_unread_exists(): void
|
|
|
|
|
{
|
|
|
|
|
$feed = Feed::factory()->create([
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'last_fetched_at' => now()->subHours(50),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
Notification::factory()
|
|
|
|
|
->type(NotificationTypeEnum::FEED_STALE)
|
|
|
|
|
->unread()
|
|
|
|
|
->create([
|
|
|
|
|
'notifiable_type' => $feed->getMorphClass(),
|
|
|
|
|
'notifiable_id' => $feed->id,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->dispatch();
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseCount('notifications', 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_creates_new_notification_when_previous_is_read(): void
|
|
|
|
|
{
|
|
|
|
|
$feed = Feed::factory()->create([
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'last_fetched_at' => now()->subHours(50),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
Notification::factory()
|
|
|
|
|
->type(NotificationTypeEnum::FEED_STALE)
|
|
|
|
|
->read()
|
|
|
|
|
->create([
|
|
|
|
|
'notifiable_type' => $feed->getMorphClass(),
|
|
|
|
|
'notifiable_id' => $feed->id,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->dispatch();
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseCount('notifications', 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_threshold_zero_disables_check(): void
|
|
|
|
|
{
|
|
|
|
|
Setting::setFeedStalenessThreshold(0);
|
|
|
|
|
|
|
|
|
|
Feed::factory()->create([
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'last_fetched_at' => now()->subHours(100),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->dispatch();
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseCount('notifications', 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_never_fetched_feed_creates_notification(): void
|
|
|
|
|
{
|
|
|
|
|
$feed = Feed::factory()->create([
|
|
|
|
|
'is_active' => true,
|
|
|
|
|
'last_fetched_at' => null,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->dispatch();
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('notifications', [
|
|
|
|
|
'type' => NotificationTypeEnum::FEED_STALE->value,
|
|
|
|
|
'notifiable_type' => $feed->getMorphClass(),
|
|
|
|
|
'notifiable_id' => $feed->id,
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function dispatch(): void
|
|
|
|
|
{
|
2026-03-18 20:01:25 +01:00
|
|
|
(new CheckFeedStalenessJob)->handle(app(NotificationService::class));
|
2026-03-09 17:32:55 +01:00
|
|
|
}
|
|
|
|
|
}
|