fedi-feed-router/tests/Feature/Livewire/FeedsTest.php

287 lines
9.1 KiB
PHP

<?php
namespace Tests\Feature\Livewire;
use App\Livewire\Feeds;
use App\Models\Feed;
use App\Models\Language;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;
class FeedsTest extends TestCase
{
use RefreshDatabase;
public function test_add_button_renders_when_feeds_exist(): void
{
Feed::factory()->create(['name' => 'Existing Feed']);
Livewire::test(Feeds::class)
->assertSee('Add Feed')
->assertSee('Existing Feed');
}
public function test_add_button_renders_in_empty_state(): void
{
Livewire::test(Feeds::class)
->assertSee('No feeds')
->assertSee('Add Feed');
}
public function test_open_create_modal_shows_modal(): void
{
Livewire::test(Feeds::class)
->assertSet('showCreateModal', false)
->call('openCreateModal')
->assertSet('showCreateModal', true);
}
public function test_create_feed_requires_name(): void
{
$language = Language::factory()->english()->create();
Livewire::test(Feeds::class)
->call('openCreateModal')
->set('newProvider', 'guardian')
->set('newLanguageId', $language->id)
->call('createFeed')
->assertHasErrors(['newName' => 'required']);
}
public function test_create_feed_requires_provider(): void
{
$language = Language::factory()->english()->create();
Livewire::test(Feeds::class)
->call('openCreateModal')
->set('newName', 'Tech News')
->set('newLanguageId', $language->id)
->call('createFeed')
->assertHasErrors(['newProvider' => 'required']);
}
public function test_create_feed_requires_language(): void
{
Livewire::test(Feeds::class)
->call('openCreateModal')
->set('newName', 'Tech News')
->set('newProvider', 'guardian')
->call('createFeed')
->assertHasErrors(['newLanguageId' => 'required']);
}
public function test_create_feed_rejects_unknown_provider(): void
{
$language = Language::factory()->english()->create();
Livewire::test(Feeds::class)
->call('openCreateModal')
->set('newName', 'Tech News')
->set('newProvider', 'nonexistent')
->set('newLanguageId', $language->id)
->call('createFeed')
->assertHasErrors('newProvider');
$this->assertDatabaseCount('feeds', 0);
}
public function test_create_feed_succeeds_and_resolves_url(): void
{
$language = Language::factory()->english()->create();
Livewire::test(Feeds::class)
->call('openCreateModal')
->set('newName', 'Guardian News')
->set('newProvider', 'guardian')
->set('newLanguageId', $language->id)
->set('newDescription', 'British daily')
->call('createFeed')
->assertHasNoErrors()
->assertSet('showCreateModal', false);
$this->assertDatabaseHas('feeds', [
'name' => 'Guardian News',
'provider' => 'guardian',
'language_id' => $language->id,
'url' => 'https://www.theguardian.com/international/rss',
'description' => 'British daily',
'is_active' => true,
]);
}
public function test_create_feed_leaves_description_null_when_blank(): void
{
$language = Language::factory()->english()->create();
Livewire::test(Feeds::class)
->call('openCreateModal')
->set('newName', 'Guardian News')
->set('newProvider', 'guardian')
->set('newLanguageId', $language->id)
->call('createFeed')
->assertHasNoErrors();
$this->assertDatabaseHas('feeds', [
'name' => 'Guardian News',
'description' => null,
]);
}
public function test_create_feed_surfaces_invalid_provider_language_combination(): void
{
// Belga only supports 'en'; a non-'en' language triggers InvalidArgumentException in the action.
$language = Language::factory()->create(['short_code' => 'nl', 'name' => 'Dutch', 'is_active' => true]);
Livewire::test(Feeds::class)
->call('openCreateModal')
->set('newName', 'Belga NL')
->set('newProvider', 'belga')
->set('newLanguageId', $language->id)
->call('createFeed')
->assertHasErrors('newProvider')
->assertSet('showCreateModal', true);
$this->assertDatabaseCount('feeds', 0);
}
public function test_toggle_flips_active_state(): void
{
$feed = Feed::factory()->create(['is_active' => true]);
Livewire::test(Feeds::class)
->call('toggle', $feed->id);
$this->assertFalse($feed->fresh()->is_active);
}
public function test_feed_cards_show_an_edit_action(): void
{
Feed::factory()->create(['name' => 'VRT Nieuws']);
Livewire::test(Feeds::class)
->assertSee('Edit VRT Nieuws');
}
public function test_open_edit_modal_prefills_the_current_values(): void
{
$feed = Feed::factory()->create([
'name' => 'VRT Nieuws',
'description' => 'Flemish public broadcaster',
]);
Livewire::test(Feeds::class)
->assertSet('editingFeedId', null)
->call('openEditModal', $feed->id)
->assertSet('editingFeedId', $feed->id)
->assertSet('editName', 'VRT Nieuws')
->assertSet('editDescription', 'Flemish public broadcaster')
->assertSee('Edit Feed');
}
public function test_open_edit_modal_prefills_a_null_description_as_blank(): void
{
$feed = Feed::factory()->create(['description' => null]);
Livewire::test(Feeds::class)
->call('openEditModal', $feed->id)
->assertSet('editDescription', '');
}
public function test_update_feed_persists_the_changes_and_closes_the_modal(): void
{
$feed = Feed::factory()->create([
'name' => 'Old Name',
'description' => 'Old description',
]);
Livewire::test(Feeds::class)
->call('openEditModal', $feed->id)
->set('editName', 'New Name')
->set('editDescription', 'New description')
->call('updateFeed')
->assertSet('editingFeedId', null)
->assertHasNoErrors();
$feed->refresh();
$this->assertSame('New Name', $feed->name);
$this->assertSame('New description', $feed->description);
}
public function test_update_feed_requires_a_name(): void
{
$feed = Feed::factory()->create(['name' => 'Original']);
Livewire::test(Feeds::class)
->call('openEditModal', $feed->id)
->set('editName', '')
->call('updateFeed')
->assertHasErrors(['editName' => 'required']);
$this->assertSame('Original', $feed->fresh()->name);
}
public function test_update_feed_rejects_a_name_over_the_length_limit(): void
{
$feed = Feed::factory()->create(['name' => 'Original']);
Livewire::test(Feeds::class)
->call('openEditModal', $feed->id)
->set('editName', str_repeat('a', 256))
->call('updateFeed')
->assertHasErrors(['editName' => 'max']);
$this->assertSame('Original', $feed->fresh()->name);
}
public function test_update_feed_stores_a_blank_description_as_null(): void
{
$feed = Feed::factory()->create(['description' => 'Has one']);
Livewire::test(Feeds::class)
->call('openEditModal', $feed->id)
->set('editDescription', '')
->call('updateFeed');
$this->assertNull($feed->fresh()->description);
}
public function test_update_feed_leaves_the_source_identity_untouched(): void
{
$feed = Feed::factory()->create(['name' => 'Original']);
$before = $feed->only(['url', 'provider', 'language_id', 'type']);
Livewire::test(Feeds::class)
->call('openEditModal', $feed->id)
->set('editName', 'Renamed')
->call('updateFeed');
$this->assertSame($before, $feed->fresh()->only(['url', 'provider', 'language_id', 'type']));
}
public function test_close_edit_modal_discards_the_edit(): void
{
$feed = Feed::factory()->create(['name' => 'Original']);
Livewire::test(Feeds::class)
->call('openEditModal', $feed->id)
->set('editName', 'Discarded')
->call('closeEditModal')
->assertSet('editingFeedId', null);
$this->assertSame('Original', $feed->fresh()->name);
}
public function test_update_feed_does_nothing_without_an_open_modal(): void
{
$feed = Feed::factory()->create(['name' => 'Original']);
Livewire::test(Feeds::class)
->set('editName', 'Should not apply')
->call('updateFeed')
->assertHasNoErrors();
$this->assertSame('Original', $feed->fresh()->name);
}
}