create(['is_admin' => true]); $app = Application::factory()->create([ 'name' => 'Test Application', 'icon' => 'https://example.com/test-icon.png' ]); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id); expect($component->get('app')->id)->toBe($app->id); expect($component->get('name'))->toBe('Test Application'); expect($component->get('icon'))->toBe('https://example.com/test-icon.png'); }); it('updates icon when query is changed', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create(); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id) ->set('query', 'nextcloud'); expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/nextcloud.webp'); }); it('does not update icon when query is empty', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create(); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id) ->set('query', 'test') ->set('query', ''); // Icon should remain the same as before setting empty query expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/test.webp'); }); it('converts query to kebab case for icon URL', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create(); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id) ->set('query', 'Home Assistant'); expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/home-assistant.webp'); }); it('can save updated app information', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create([ 'name' => 'Original Name', 'icon' => 'https://example.com/original.png' ]); $this->actingAs($user); Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id) ->set('name', 'Updated App Name') ->set('icon', 'https://example.com/new-icon.png') ->call('save'); $app->refresh(); expect($app->name)->toBe('Updated App Name'); expect($app->icon)->toBe('https://example.com/new-icon.png'); }); it('dispatches app-updated event after saving', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create(); $this->actingAs($user); Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id) ->set('name', 'Updated App Name') ->call('save') ->assertDispatched('app-updated', ['id' => $app->id]); }); it('can update only name without changing icon', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create([ 'name' => 'Original Name', 'icon' => 'https://example.com/original.png' ]); $this->actingAs($user); $originalIcon = $app->icon; Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id) ->set('name', 'New Name Only') ->call('save'); $app->refresh(); expect($app->name)->toBe('New Name Only'); expect($app->icon)->toBe($originalIcon); }); it('can update only icon without changing name', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create([ 'name' => 'Original Name', 'icon' => 'https://example.com/original.png' ]); $this->actingAs($user); $originalName = $app->name; Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id) ->set('icon', 'https://example.com/new-icon-only.png') ->call('save'); $app->refresh(); expect($app->name)->toBe($originalName); expect($app->icon)->toBe('https://example.com/new-icon-only.png'); }); it('handles special characters in query correctly', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create(); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id) ->set('query', 'App with Spaces & Special-Chars!'); expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/app-with-spaces&-special--chars!.webp'); }); it('loads app with null icon correctly', function () { $user = User::factory()->create(['is_admin' => true]); $appWithNullIcon = Application::factory()->create(['icon' => null]); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $appWithNullIcon->id); expect($component->get('icon'))->toBeNull(); expect($component->get('name'))->toBe($appWithNullIcon->name); }); it('preserves original icon when setting empty query', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create(['icon' => 'https://example.com/original.png']); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id); $originalIcon = $component->get('icon'); // Setting empty query should not change the icon $component->set('query', ''); expect($component->get('icon'))->toBe($originalIcon); }); it('updates properties correctly when loading different apps', function () { $user = User::factory()->create(['is_admin' => true]); $app1 = Application::factory()->create([ 'name' => 'First Application', 'icon' => 'https://example.com/first-icon.png' ]); $app2 = Application::factory()->create([ 'name' => 'Second Application', 'icon' => 'https://example.com/second-icon.png' ]); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $app1->id); expect($component->get('name'))->toBe('First Application'); $component->call('loadApp', $app2->id); expect($component->get('app')->id)->toBe($app2->id); expect($component->get('name'))->toBe('Second Application'); expect($component->get('icon'))->toBe('https://example.com/second-icon.png'); }); it('query to icon conversion handles edge cases', function () { $user = User::factory()->create(['is_admin' => true]); $app = Application::factory()->create(); $this->actingAs($user); $component = Livewire::test(AppInfoModal::class) ->call('loadApp', $app->id); // Test uppercase conversion $component->set('query', 'NEXTCLOUD'); expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/n-e-x-t-c-l-o-u-d.webp'); // Test numbers and special chars $component->set('query', 'App123-test_name'); expect($component->get('icon'))->toBe('https://cdn.jsdelivr.net/gh/selfhst/icons/webp/app123-test_name.webp'); });