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); } }