Improve recordings list sorting and live show-page status updates.
Add sortable columns with a fixed status width, and keep the show page in sync via Echo, polling, and Alpine hydrate while transcription runs.
This commit is contained in:
@@ -125,8 +125,8 @@ class IndexTest extends TestCase
|
||||
|
||||
Livewire::test(Index::class)
|
||||
->assertSee('wire:poll', false)
|
||||
->assertSee('Transcribing locally…')
|
||||
->assertSee('40%')
|
||||
->assertSee('Transcribing')
|
||||
->assertDontSee('Transcribing locally…')
|
||||
->assertSeeHtml('bg-amber-400');
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ class IndexTest extends TestCase
|
||||
Livewire::test(Index::class)
|
||||
->assertSee('Waiting in line')
|
||||
->assertSee('Queued')
|
||||
->assertSee('Queued — waiting to start…')
|
||||
->assertDontSee('Queued — waiting to start…')
|
||||
->assertDontSee('5%')
|
||||
->assertSeeHtml('bg-zinc-400/15')
|
||||
->assertDontSeeHtml('bg-amber-400');
|
||||
@@ -282,4 +282,59 @@ class IndexTest extends TestCase
|
||||
|
||||
$this->assertDatabaseHas('recordings', ['id' => $recording->id]);
|
||||
}
|
||||
|
||||
public function test_recordings_can_be_sorted_by_title(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
Recording::query()->create([
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Zebra',
|
||||
'original_filename' => 'z.mp3',
|
||||
'file_path' => 'recordings/z.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'done',
|
||||
'created_at' => now()->subDay(),
|
||||
]);
|
||||
|
||||
Recording::query()->create([
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Alpha',
|
||||
'original_filename' => 'a.mp3',
|
||||
'file_path' => 'recordings/a.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'done',
|
||||
'created_at' => now(),
|
||||
]);
|
||||
|
||||
Livewire::test(Index::class)
|
||||
->call('sort', 'title')
|
||||
->assertSet('sortBy', 'title')
|
||||
->assertSet('sortDirection', 'asc')
|
||||
->assertSeeInOrder(['Alpha', 'Zebra'])
|
||||
->call('sort', 'title')
|
||||
->assertSet('sortDirection', 'desc')
|
||||
->assertSeeInOrder(['Zebra', 'Alpha']);
|
||||
}
|
||||
|
||||
public function test_invalid_sort_column_is_ignored(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
Recording::query()->create([
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Only one',
|
||||
'original_filename' => 'one.mp3',
|
||||
'file_path' => 'recordings/one.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'done',
|
||||
]);
|
||||
|
||||
Livewire::test(Index::class)
|
||||
->call('sort', 'not_a_column')
|
||||
->assertSet('sortBy', 'uploaded')
|
||||
->assertSet('sortDirection', 'desc');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +59,81 @@ class ShowTest extends TestCase
|
||||
|
||||
$this->assertDatabaseMissing('recordings', ['id' => $recording->id]);
|
||||
}
|
||||
|
||||
public function test_show_polls_while_transcription_is_active(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
$recording = Recording::query()->create([
|
||||
'user_id' => $user->id,
|
||||
'title' => 'In progress',
|
||||
'original_filename' => 'active.mp3',
|
||||
'file_path' => 'recordings/active.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'processing',
|
||||
'transcription_progress' => 'Queued — waiting to start…',
|
||||
'transcription_percent' => null,
|
||||
'transcription_driver' => 'local',
|
||||
'transcription_started_at' => now(),
|
||||
]);
|
||||
|
||||
Livewire::test(Show::class, ['recording' => $recording])
|
||||
->assertSee('wire:poll', false)
|
||||
->assertSee('Queued — waiting to start…');
|
||||
}
|
||||
|
||||
public function test_show_does_not_poll_when_transcription_is_idle(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
$recording = Recording::query()->create([
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Finished',
|
||||
'original_filename' => 'done.mp3',
|
||||
'file_path' => 'recordings/done.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'done',
|
||||
'transcript' => 'all done',
|
||||
]);
|
||||
|
||||
Livewire::test(Show::class, ['recording' => $recording])
|
||||
->assertDontSee('wire:poll', false);
|
||||
}
|
||||
|
||||
public function test_show_refreshes_recording_on_transcription_broadcast(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
$recording = Recording::query()->create([
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Live update',
|
||||
'original_filename' => 'live.mp3',
|
||||
'file_path' => 'recordings/live.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'pending',
|
||||
'transcription_progress' => 'Queued — waiting to start…',
|
||||
'transcription_driver' => 'local',
|
||||
'transcription_started_at' => now(),
|
||||
]);
|
||||
|
||||
$component = Livewire::test(Show::class, ['recording' => $recording]);
|
||||
|
||||
$recording->update([
|
||||
'transcription_status' => 'processing',
|
||||
'transcription_progress' => 'Transcribing locally…',
|
||||
'transcription_percent' => 40,
|
||||
]);
|
||||
|
||||
$component
|
||||
->call('onTranscriptionUpdated', [
|
||||
'id' => $recording->id,
|
||||
'status' => 'processing',
|
||||
])
|
||||
->assertSet('recording.transcription_status', 'processing')
|
||||
->assertSet('recording.transcription_percent', 40)
|
||||
->assertSee('Transcribing locally…');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user