create(); $recording = Recording::query()->create([ 'user_id' => $user->id, 'title' => 'Show me', 'original_filename' => 'show.mp3', 'file_path' => 'recordings/show.mp3', 'file_size_bytes' => 100, 'transcription_status' => 'done', 'transcript' => 'Finished text', ]); $this->actingAs($user) ->get(route('recordings.show', $recording)) ->assertOk() ->assertSeeLivewire(Show::class) ->assertSee('Show me') ->assertSee('Play', false); } public function test_user_can_delete_own_recording(): void { Storage::fake('local'); Storage::disk('local')->put('recordings/delete-me.mp3', 'bytes'); $user = User::factory()->create(); $this->actingAs($user); $recording = Recording::query()->create([ 'user_id' => $user->id, 'title' => 'Delete me', 'original_filename' => 'delete-me.mp3', 'file_path' => 'recordings/delete-me.mp3', 'file_size_bytes' => 5, 'transcription_status' => 'done', ]); Livewire::test(Show::class, ['recording' => $recording]) ->call('delete') ->assertRedirect(route('recordings.index')); $this->assertDatabaseMissing('recordings', ['id' => $recording->id]); } public function test_show_polls_while_transcription_is_queued(): 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' => 'pending', '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) ->assertDontSee('echo-private', false) ->assertSee('Queued — waiting to start…'); } public function test_show_does_not_poll_while_transcription_is_processing(): void { $user = User::factory()->create(); $this->actingAs($user); $recording = Recording::query()->create([ 'user_id' => $user->id, 'title' => 'Live stream', 'original_filename' => 'active.mp3', 'file_path' => 'recordings/active.mp3', 'file_size_bytes' => 100, 'transcription_status' => 'processing', 'transcription_progress' => 'Transcribing locally…', 'transcription_percent' => 20, 'transcription_driver' => 'local', 'transcription_started_at' => now(), ]); Livewire::test(Show::class, ['recording' => $recording]) ->assertDontSee('wire:poll', false) ->assertSee('userId', false); } public function test_show_page_includes_partial_transcript_while_processing(): void { $user = User::factory()->create(); $this->actingAs($user); $recording = Recording::query()->create([ 'user_id' => $user->id, 'title' => 'Live words', 'original_filename' => 'active.mp3', 'file_path' => 'recordings/active.mp3', 'file_size_bytes' => 100, 'transcription_status' => 'processing', 'transcription_progress' => 'Transcribing locally…', 'transcription_percent' => 62, 'transcription_driver' => 'local', 'transcription_started_at' => now(), 'transcript' => 'Live partial sentence from whisper', ]); Livewire::test(Show::class, ['recording' => $recording]) ->assertSee('Live partial sentence from whisper') ->assertSee('status.transcript', false); } public function test_show_page_includes_live_whisper_segment_bindings(): void { $user = User::factory()->create(); $this->actingAs($user); $recording = Recording::query()->create([ 'user_id' => $user->id, 'title' => 'Verbose live', 'original_filename' => 'active.mp3', 'file_path' => 'recordings/active.mp3', 'file_size_bytes' => 100, 'transcription_status' => 'processing', 'transcription_driver' => 'local', 'transcription_started_at' => now(), 'transcript' => 'Hello', 'transcription_verbose' => [ 'language' => 'en', 'duration' => 4.0, 'segments' => [ [ 'text' => 'Hello', 'start' => 0.0, 'end' => 1.0, 'avg_logprob' => -0.1, 'words' => [ ['word' => 'Hello', 'start' => 0.0, 'end' => 1.0, 'probability' => 0.9], ], ], ], ], ]); Livewire::test(Show::class, ['recording' => $recording]) ->assertSee('whisper.segments', false) ->assertSee('whisper.language', false) ->assertSee('Hello'); } 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_poll_refresh_picks_up_processing_status(): 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('$refresh') ->assertSet('recording.transcription_status', 'processing') ->assertSet('recording.transcription_percent', 40) ->assertSee('Transcribing locally…'); } public function test_show_poll_refresh_picks_up_completed_transcript(): void { $user = User::factory()->create(); $this->actingAs($user); $recording = Recording::query()->create([ 'user_id' => $user->id, 'title' => 'Almost done', 'original_filename' => 'live.mp3', 'file_path' => 'recordings/live.mp3', 'file_size_bytes' => 100, 'transcription_status' => 'processing', 'transcription_progress' => 'Transcribing locally…', 'transcription_percent' => 90, 'transcription_driver' => 'local', 'transcription_started_at' => now(), 'transcript' => 'Partial', ]); $component = Livewire::test(Show::class, ['recording' => $recording]); $recording->update([ 'transcription_status' => 'done', 'transcription_percent' => 100, 'transcript' => 'Finished live transcript', 'transcribed_at' => now(), ]); $component ->call('$refresh') ->assertSet('recording.transcription_status', 'done') ->assertSet('recording.transcription_percent', 100) ->assertSee('Finished live transcript'); } public function test_show_alpine_root_key_does_not_include_percent(): void { $user = User::factory()->create(); $this->actingAs($user); $recording = Recording::query()->create([ 'user_id' => $user->id, 'title' => 'Stable key', 'original_filename' => 'live.mp3', 'file_path' => 'recordings/live.mp3', 'file_size_bytes' => 100, 'transcription_status' => 'processing', 'transcription_progress' => 'Transcribing locally…', 'transcription_percent' => 62, 'transcription_driver' => 'local', 'transcription_started_at' => now(), ]); Livewire::test(Show::class, ['recording' => $recording]) ->assertSee('wire:ignore.self', false) ->assertSee('transcription-ui-'.$recording->id.'-processing-', false) ->assertDontSee('transcription-ui-'.$recording->id.'-processing-62', false); } }