Use local faster-whisper only for transcription.
Drop cloud and Ollama engine choices so audio stays on-machine via Docker Whisper, and tighten orphan detection plus UI around a single local flow.
This commit is contained in:
@@ -84,7 +84,7 @@ class RecordingUploadTest extends TestCase
|
||||
->assertSessionHasErrors('audio');
|
||||
}
|
||||
|
||||
public function test_user_can_queue_cloud_transcription(): void
|
||||
public function test_user_can_queue_local_transcription(): void
|
||||
{
|
||||
$recording = Recording::query()->create([
|
||||
'title' => 'Dictation',
|
||||
@@ -97,34 +97,16 @@ class RecordingUploadTest extends TestCase
|
||||
// Fake AI so the afterResponse job (sync) does not call a real provider.
|
||||
Transcription::fake(['Queued transcription text.']);
|
||||
|
||||
$this->post(route('recordings.transcribe', $recording), [
|
||||
'driver' => 'cloud',
|
||||
])->assertRedirect();
|
||||
$this->post(route('recordings.transcribe', $recording))
|
||||
->assertRedirect();
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('cloud', $recording->transcription_driver);
|
||||
$this->assertSame('local', $recording->transcription_driver);
|
||||
$this->assertContains($recording->transcription_status, ['pending', 'processing', 'done']);
|
||||
$this->assertNotNull($recording->transcription_started_at);
|
||||
$this->assertNotNull($recording->transcription_progress);
|
||||
}
|
||||
|
||||
public function test_ollama_driver_requires_url(): void
|
||||
{
|
||||
$recording = Recording::query()->create([
|
||||
'title' => 'Secret call',
|
||||
'original_filename' => 'call.mp3',
|
||||
'file_path' => 'recordings/call.mp3',
|
||||
'file_size_bytes' => 2048,
|
||||
'transcription_status' => 'pending',
|
||||
]);
|
||||
|
||||
$this->from(route('recordings.show', $recording))
|
||||
->post(route('recordings.transcribe', $recording), [
|
||||
'driver' => 'ollama',
|
||||
])
|
||||
->assertSessionHasErrors('ollama_url');
|
||||
}
|
||||
|
||||
public function test_transcription_status_endpoint_returns_progress(): void
|
||||
{
|
||||
$recording = Recording::query()->create([
|
||||
@@ -133,19 +115,19 @@ class RecordingUploadTest extends TestCase
|
||||
'file_path' => 'recordings/live.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'processing',
|
||||
'transcription_progress' => 'Waiting for cloud transcript…',
|
||||
'transcription_progress' => 'Transcribing locally…',
|
||||
'transcription_percent' => 55,
|
||||
'transcription_driver' => 'cloud',
|
||||
'transcription_driver' => 'local',
|
||||
'transcription_started_at' => now()->subSeconds(12),
|
||||
]);
|
||||
|
||||
$this->getJson(route('recordings.transcription-status', $recording))
|
||||
->assertOk()
|
||||
->assertJsonPath('status', 'processing')
|
||||
->assertJsonPath('progress', 'Waiting for cloud transcript…')
|
||||
->assertJsonPath('progress', 'Transcribing locally…')
|
||||
->assertJsonPath('percent', 55)
|
||||
->assertJsonPath('is_active', true)
|
||||
->assertJsonPath('driver_label', 'Cloud (OpenAI Whisper)');
|
||||
->assertJsonPath('driver_label', 'Local (faster-whisper)');
|
||||
}
|
||||
|
||||
public function test_transcription_job_stores_transcript(): void
|
||||
@@ -161,7 +143,7 @@ class RecordingUploadTest extends TestCase
|
||||
'file_path' => 'recordings/sample.mp3',
|
||||
'file_size_bytes' => 12,
|
||||
'transcription_status' => 'pending',
|
||||
'transcription_driver' => 'cloud',
|
||||
'transcription_driver' => 'local',
|
||||
]);
|
||||
|
||||
(new TranscribeRecording($recording))->handle(app(TranscriptionService::class));
|
||||
@@ -189,7 +171,7 @@ class RecordingUploadTest extends TestCase
|
||||
'file_path' => 'recordings/bad.mp3',
|
||||
'file_size_bytes' => 12,
|
||||
'transcription_status' => 'pending',
|
||||
'transcription_driver' => 'cloud',
|
||||
'transcription_driver' => 'local',
|
||||
]);
|
||||
|
||||
try {
|
||||
@@ -215,8 +197,8 @@ class RecordingUploadTest extends TestCase
|
||||
'transcription_progress' => 'Transcribing locally…',
|
||||
'transcription_percent' => 50,
|
||||
'transcription_driver' => 'local',
|
||||
'transcription_started_at' => now()->subMinutes(5),
|
||||
'updated_at' => now()->subMinutes(5),
|
||||
'transcription_started_at' => now()->subMinutes(20),
|
||||
'updated_at' => now()->subMinutes(20),
|
||||
]);
|
||||
|
||||
$this->getJson(route('recordings.transcription-status', $recording))
|
||||
@@ -229,6 +211,30 @@ class RecordingUploadTest extends TestCase
|
||||
$this->assertStringContainsString('worker stopped', $recording->transcription_error);
|
||||
}
|
||||
|
||||
public function test_recent_processing_is_not_marked_orphaned(): void
|
||||
{
|
||||
$recording = Recording::query()->create([
|
||||
'title' => 'Still working',
|
||||
'original_filename' => 'working.mp3',
|
||||
'file_path' => 'recordings/working.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'processing',
|
||||
'transcription_progress' => 'Transcribing locally…',
|
||||
'transcription_percent' => 50,
|
||||
'transcription_driver' => 'local',
|
||||
'transcription_started_at' => now()->subMinutes(2),
|
||||
'updated_at' => now()->subMinutes(2),
|
||||
]);
|
||||
|
||||
$this->getJson(route('recordings.transcription-status', $recording))
|
||||
->assertOk()
|
||||
->assertJsonPath('status', 'processing')
|
||||
->assertJsonPath('is_active', true);
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('processing', $recording->transcription_status);
|
||||
}
|
||||
|
||||
public function test_orphaned_processing_can_be_restarted(): void
|
||||
{
|
||||
Transcription::fake(['Recovered transcript.']);
|
||||
@@ -244,12 +250,11 @@ class RecordingUploadTest extends TestCase
|
||||
'updated_at' => now()->subMinutes(10),
|
||||
]);
|
||||
|
||||
$this->post(route('recordings.transcribe', $recording), [
|
||||
'driver' => 'cloud',
|
||||
])->assertRedirect();
|
||||
$this->post(route('recordings.transcribe', $recording))
|
||||
->assertRedirect();
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('cloud', $recording->transcription_driver);
|
||||
$this->assertSame('local', $recording->transcription_driver);
|
||||
$this->assertContains($recording->transcription_status, ['pending', 'processing', 'done']);
|
||||
}
|
||||
|
||||
@@ -277,12 +282,12 @@ class RecordingUploadTest extends TestCase
|
||||
$this->assertFalse($recording->isTranscribing());
|
||||
}
|
||||
|
||||
public function test_user_can_start_a_different_engine_while_processing(): void
|
||||
public function test_user_can_restart_transcription_while_processing(): void
|
||||
{
|
||||
Transcription::fake(['Switched engine transcript.']);
|
||||
Transcription::fake(['Restarted transcript.']);
|
||||
|
||||
$recording = Recording::query()->create([
|
||||
'title' => 'Switch me',
|
||||
'title' => 'Restart me while busy',
|
||||
'original_filename' => 'switch.mp3',
|
||||
'file_path' => 'recordings/switch.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
@@ -291,14 +296,12 @@ class RecordingUploadTest extends TestCase
|
||||
'transcription_started_at' => now()->subMinute(),
|
||||
]);
|
||||
|
||||
$this->post(route('recordings.transcribe', $recording), [
|
||||
'driver' => 'cloud',
|
||||
])
|
||||
$this->post(route('recordings.transcribe', $recording))
|
||||
->assertRedirect()
|
||||
->assertSessionHas('success');
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('cloud', $recording->transcription_driver);
|
||||
$this->assertSame('local', $recording->transcription_driver);
|
||||
$this->assertContains($recording->transcription_status, ['pending', 'processing', 'done']);
|
||||
$this->assertNull($recording->transcription_error);
|
||||
}
|
||||
@@ -316,7 +319,7 @@ class RecordingUploadTest extends TestCase
|
||||
'file_path' => 'recordings/ignore.mp3',
|
||||
'file_size_bytes' => 12,
|
||||
'transcription_status' => 'processing',
|
||||
'transcription_driver' => 'cloud',
|
||||
'transcription_driver' => 'local',
|
||||
'transcription_started_at' => now()->subMinute(),
|
||||
'transcript' => 'Previous transcript stays.',
|
||||
]);
|
||||
@@ -368,14 +371,13 @@ class RecordingUploadTest extends TestCase
|
||||
'file_path' => 'recordings/keep.mp3',
|
||||
'file_size_bytes' => 100,
|
||||
'transcription_status' => 'done',
|
||||
'transcription_driver' => 'cloud',
|
||||
'transcription_driver' => 'local',
|
||||
'transcript' => 'Old transcript text.',
|
||||
'transcribed_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
$this->post(route('recordings.transcribe', $recording), [
|
||||
'driver' => 'local',
|
||||
])->assertRedirect();
|
||||
$this->post(route('recordings.transcribe', $recording))
|
||||
->assertRedirect();
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('Old transcript text.', $recording->transcript);
|
||||
|
||||
Reference in New Issue
Block a user