fedi-feed-router/tests/Feature/NotificationTest.php

167 lines
5.4 KiB
PHP
Raw Normal View History

<?php
namespace Tests\Feature;
use App\Enums\NotificationSeverityEnum;
use App\Enums\NotificationTypeEnum;
use App\Models\Feed;
use App\Models\Notification;
use App\Services\Notification\NotificationService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class NotificationTest extends TestCase
{
use RefreshDatabase;
private NotificationService $service;
protected function setUp(): void
{
parent::setUp();
$this->service = new NotificationService;
}
public function test_send_creates_notification_with_all_fields(): void
{
$notification = $this->service->send(
NotificationTypeEnum::FEED_STALE,
NotificationSeverityEnum::WARNING,
'Feed is stale',
'Feed "VRT" has not returned new articles in 24 hours.',
data: ['hours_stale' => 24],
);
$this->assertDatabaseHas('notifications', [
'type' => 'feed_stale',
'severity' => 'warning',
'title' => 'Feed is stale',
]);
$this->assertEquals(['hours_stale' => 24], $notification->data);
$this->assertNull($notification->read_at);
}
public function test_info_convenience_method(): void
{
$notification = $this->service->info('Test title', 'Test message');
$this->assertEquals(NotificationTypeEnum::GENERAL, $notification->type);
$this->assertEquals(NotificationSeverityEnum::INFO, $notification->severity);
}
public function test_warning_convenience_method(): void
{
$notification = $this->service->warning('Warning title', 'Warning message');
$this->assertEquals(NotificationSeverityEnum::WARNING, $notification->severity);
}
public function test_error_convenience_method(): void
{
$notification = $this->service->error('Error title', 'Error message');
$this->assertEquals(NotificationSeverityEnum::ERROR, $notification->severity);
}
public function test_mark_as_read(): void
{
$notification = Notification::factory()->unread()->create();
$this->assertFalse($notification->isRead());
$notification->markAsRead();
$this->assertTrue($notification->fresh()->isRead());
$this->assertNotNull($notification->fresh()->read_at);
}
public function test_mark_all_as_read(): void
{
Notification::factory()->count(3)->unread()->create();
Notification::factory()->count(2)->read()->create();
$this->assertEquals(3, Notification::unread()->count());
Notification::markAllAsRead();
$this->assertEquals(0, Notification::unread()->count());
}
public function test_unread_scope(): void
{
Notification::factory()->count(2)->unread()->create();
Notification::factory()->count(3)->read()->create();
$this->assertEquals(2, Notification::unread()->count());
}
public function test_recent_scope_limits_to_50(): void
{
Notification::factory()->count(60)->create();
$this->assertCount(50, Notification::recent()->get());
}
public function test_enums_cast_correctly(): void
{
$notification = Notification::factory()->create([
'type' => NotificationTypeEnum::PUBLISH_FAILED,
'severity' => NotificationSeverityEnum::ERROR,
]);
$fresh = Notification::find($notification->id);
$this->assertInstanceOf(NotificationTypeEnum::class, $fresh->type);
$this->assertInstanceOf(NotificationSeverityEnum::class, $fresh->severity);
$this->assertEquals(NotificationTypeEnum::PUBLISH_FAILED, $fresh->type);
$this->assertEquals(NotificationSeverityEnum::ERROR, $fresh->severity);
}
public function test_notifiable_morph_to_relationship(): void
{
$feed = Feed::factory()->create();
$notification = $this->service->send(
NotificationTypeEnum::FEED_STALE,
NotificationSeverityEnum::WARNING,
'Feed stale',
'No new articles',
notifiable: $feed,
);
$fresh = Notification::find($notification->id);
$this->assertInstanceOf(Feed::class, $fresh->notifiable);
$this->assertEquals($feed->id, $fresh->notifiable->id);
}
public function test_notification_without_notifiable(): void
{
$notification = $this->service->info('General notice', 'Something happened');
$this->assertNull($notification->notifiable_type);
$this->assertNull($notification->notifiable_id);
$this->assertNull($notification->notifiable);
}
public function test_notification_type_enum_labels(): void
{
$this->assertEquals('General', NotificationTypeEnum::GENERAL->label());
$this->assertEquals('Feed Stale', NotificationTypeEnum::FEED_STALE->label());
$this->assertEquals('Publish Failed', NotificationTypeEnum::PUBLISH_FAILED->label());
$this->assertEquals('Credential Expired', NotificationTypeEnum::CREDENTIAL_EXPIRED->label());
}
public function test_data_stores_null_when_empty(): void
{
$notification = $this->service->info('Title', 'Message');
$this->assertNull($notification->data);
}
public function test_data_stores_array_when_provided(): void
{
$notification = $this->service->info('Title', 'Message', data: ['key' => 'value']);
$this->assertEquals(['key' => 'value'], $notification->data);
}
}