From 4eeaf995059d1ba771fc21ba3b5b9a9470247743 Mon Sep 17 00:00:00 2001 From: Ivan Moroz Date: Tue, 2 Jun 2026 10:39:34 +0300 Subject: [PATCH] CONV-172: Add search input Co-Authored-By: Claude Sonnet 4.6 --- app/Livewire/RecentConversionsTable.php | 13 +++ .../recent-conversions-table.blade.php | 9 +++ .../Livewire/RecentConversionsTableTest.php | 80 +++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/app/Livewire/RecentConversionsTable.php b/app/Livewire/RecentConversionsTable.php index 53f1fd2..be78502 100644 --- a/app/Livewire/RecentConversionsTable.php +++ b/app/Livewire/RecentConversionsTable.php @@ -7,15 +7,28 @@ use App\Enums\ConversionStatus; use App\Models\ConversionJob; use Illuminate\Contracts\View\View; +use Illuminate\Database\Eloquent\Builder; use Livewire\Component; class RecentConversionsTable extends Component { + public string $search = ''; + public function render(): View { $conversions = ConversionJob::query() ->where('user_id', auth()->id()) ->with(['sourceFile', 'resultFile']) + ->when($this->search !== '', function (Builder $query) { + $search = trim($this->search); + + $query->where(function (Builder $query) use ($search) { + $query->where('source_format', 'like', "%{$search}%") + ->orWhere('target_format', 'like', "%{$search}%") + ->orWhereHas('sourceFile', fn (Builder $q) => $q->where('original_name', 'like', "%{$search}%") + ); + }); + }) ->latest() ->get(); diff --git a/resources/views/livewire/recent-conversions-table.blade.php b/resources/views/livewire/recent-conversions-table.blade.php index 7360c69..30b40a7 100644 --- a/resources/views/livewire/recent-conversions-table.blade.php +++ b/resources/views/livewire/recent-conversions-table.blade.php @@ -1,6 +1,15 @@

Recent Conversions

+
+ +
+
@if ($conversions->isEmpty())
diff --git a/tests/Feature/Livewire/RecentConversionsTableTest.php b/tests/Feature/Livewire/RecentConversionsTableTest.php index 9314d6c..1d7116c 100644 --- a/tests/Feature/Livewire/RecentConversionsTableTest.php +++ b/tests/Feature/Livewire/RecentConversionsTableTest.php @@ -37,6 +37,86 @@ ->assertSee('Upload a file to start converting'); }); +it('searches conversions by source file name', function () { + $user = User::factory()->create(); + + $matchFile = FileRecord::factory()->for($user)->create([ + 'original_name' => 'marketing-report.png', + ]); + + $otherFile = FileRecord::factory()->for($user)->create([ + 'original_name' => 'product-photo.jpg', + ]); + + ConversionJob::factory()->for($user)->for($matchFile, 'sourceFile')->create(); + ConversionJob::factory()->for($user)->for($otherFile, 'sourceFile')->create(); + + $this->actingAs($user); + + Livewire::test(RecentConversionsTable::class) + ->set('search', 'marketing') + ->assertSee('marketing-report.png') + ->assertDontSee('product-photo.jpg'); +}); + +it('searches conversions by source format', function () { + $user = User::factory()->create(); + + $sourceA = FileRecord::factory()->for($user)->create(['original_name' => 'report.docx']); + $sourceB = FileRecord::factory()->for($user)->create(['original_name' => 'image.bmp']); + + ConversionJob::factory()->for($user)->for($sourceA, 'sourceFile')->create([ + 'source_format' => 'docx', + 'target_format' => 'jpg', + ]); + ConversionJob::factory()->for($user)->for($sourceB, 'sourceFile')->create([ + 'source_format' => 'bmp', + 'target_format' => 'webp', + ]); + + $this->actingAs($user); + + Livewire::test(RecentConversionsTable::class) + ->set('search', 'docx') + ->assertSee('DOCX') + ->assertDontSee('WEBP'); +}); + +it('searches conversions by target format', function () { + $user = User::factory()->create(); + + $sourceA = FileRecord::factory()->for($user)->create(['original_name' => 'image.bmp']); + $sourceB = FileRecord::factory()->for($user)->create(['original_name' => 'report.docx']); + + ConversionJob::factory()->for($user)->for($sourceA, 'sourceFile')->create([ + 'source_format' => 'bmp', + 'target_format' => 'webp', + ]); + ConversionJob::factory()->for($user)->for($sourceB, 'sourceFile')->create([ + 'source_format' => 'docx', + 'target_format' => 'tiff', + ]); + + $this->actingAs($user); + + Livewire::test(RecentConversionsTable::class) + ->set('search', 'webp') + ->assertSee('WEBP') + ->assertDontSee('TIFF'); +}); + +it('shows all conversions when search is empty', function () { + $user = User::factory()->create(); + + ConversionJob::factory()->count(3)->for($user)->create(); + + $this->actingAs($user); + + Livewire::test(RecentConversionsTable::class) + ->set('search', '') + ->assertViewHas('conversions', fn ($c) => $c->count() === 3); +}); + it('shows download action for completed conversion with result file', function () { $user = User::factory()->create();