Move recordings UI to Livewire pages with Flux components.
Replace controller-driven Blade views with full-page Livewire index/show/create flows so Flux tables, toasts, and uploads work natively.
This commit is contained in:
@@ -4,6 +4,9 @@ namespace Tests\Feature;
|
||||
|
||||
use App\Http\Requests\StoreRecordingRequest;
|
||||
use App\Jobs\TranscribeRecording;
|
||||
use App\Livewire\Recordings\Index;
|
||||
use App\Livewire\Recordings\Show;
|
||||
use App\Livewire\UploadRecordings;
|
||||
use App\Models\Recording;
|
||||
use App\Models\User;
|
||||
use App\Services\TranscriptionService;
|
||||
@@ -12,6 +15,7 @@ use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Laravel\Ai\Transcription;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class RecordingUploadTest extends TestCase
|
||||
@@ -54,15 +58,14 @@ class RecordingUploadTest extends TestCase
|
||||
|
||||
$file = UploadedFile::fake()->create('meeting.mp3', 500, 'audio/mpeg');
|
||||
|
||||
$response = $this->post(route('recordings.store'), [
|
||||
'audio' => [$file],
|
||||
'title' => 'Team meeting',
|
||||
]);
|
||||
Livewire::test(UploadRecordings::class)
|
||||
->set('title', 'Team meeting')
|
||||
->set('audio', [$file])
|
||||
->assertRedirect(route('recordings.show', Recording::query()->first()));
|
||||
|
||||
$recording = Recording::query()->first();
|
||||
|
||||
$this->assertNotNull($recording);
|
||||
$response->assertRedirect(route('recordings.show', $recording));
|
||||
$this->assertSame('Team meeting', $recording->title);
|
||||
$this->assertSame('pending', $recording->transcription_status);
|
||||
$this->assertSame('local', $recording->transcription_driver);
|
||||
@@ -76,16 +79,13 @@ class RecordingUploadTest extends TestCase
|
||||
Storage::fake('local');
|
||||
Bus::fake();
|
||||
|
||||
$response = $this->post(route('recordings.store'), [
|
||||
'audio' => [
|
||||
Livewire::test(UploadRecordings::class)
|
||||
->set('audio', [
|
||||
UploadedFile::fake()->createWithContent('one.mp3', str_repeat('a', 400)),
|
||||
UploadedFile::fake()->createWithContent('two.wav', str_repeat('b', 400)),
|
||||
UploadedFile::fake()->createWithContent('three.ogg', str_repeat('c', 400)),
|
||||
],
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('recordings.index'));
|
||||
$response->assertSessionHas('success');
|
||||
])
|
||||
->assertRedirect(route('recordings.index'));
|
||||
$this->assertSame(3, Recording::query()->count());
|
||||
Bus::assertDispatched(TranscribeRecording::class, 3);
|
||||
|
||||
@@ -99,9 +99,9 @@ class RecordingUploadTest extends TestCase
|
||||
{
|
||||
$this->get(route('recordings.create'))
|
||||
->assertOk()
|
||||
->assertSee('Drop audio files here')
|
||||
->assertSee('Drop audio files here or click to browse')
|
||||
->assertSee('max 2 GB each', false)
|
||||
->assertSee('name="audio[]"', false);
|
||||
->assertSeeLivewire('upload-recordings');
|
||||
}
|
||||
|
||||
public function test_files_larger_than_two_gigabytes_are_rejected(): void
|
||||
@@ -113,11 +113,9 @@ class RecordingUploadTest extends TestCase
|
||||
->create('huge.mp3', 10, 'audio/mpeg')
|
||||
->size(StoreRecordingRequest::MAX_AUDIO_KILOBYTES + 1);
|
||||
|
||||
$this->from(route('recordings.create'))
|
||||
->post(route('recordings.store'), [
|
||||
'audio' => [$file],
|
||||
])
|
||||
->assertSessionHasErrors(['audio.0']);
|
||||
Livewire::test(UploadRecordings::class)
|
||||
->set('audio', [$file])
|
||||
->assertHasErrors(['audio.0']);
|
||||
|
||||
$this->assertSame(0, Recording::query()->count());
|
||||
Bus::assertNothingDispatched();
|
||||
@@ -133,15 +131,14 @@ class RecordingUploadTest extends TestCase
|
||||
['clip.ogg', 'audio/ogg', 'ogg-bytes'],
|
||||
['talk.m4a', 'audio/mp4', 'm4a-bytes'],
|
||||
] as [$name, $mime, $contents]) {
|
||||
$response = $this->post(route('recordings.store'), [
|
||||
'audio' => [UploadedFile::fake()->createWithContent($name, $contents)],
|
||||
'title' => $name,
|
||||
]);
|
||||
Livewire::test(UploadRecordings::class)
|
||||
->set('title', $name)
|
||||
->set('audio', [UploadedFile::fake()->createWithContent($name, $contents)])
|
||||
->assertRedirect();
|
||||
|
||||
$recording = Recording::query()->where('title', $name)->first();
|
||||
|
||||
$this->assertNotNull($recording, "Failed uploading {$name}");
|
||||
$response->assertRedirect(route('recordings.show', $recording));
|
||||
Storage::disk('local')->assertExists($recording->file_path);
|
||||
}
|
||||
|
||||
@@ -152,11 +149,9 @@ class RecordingUploadTest extends TestCase
|
||||
{
|
||||
Storage::fake('local');
|
||||
|
||||
$this->from(route('recordings.create'))
|
||||
->post(route('recordings.store'), [
|
||||
'audio' => [UploadedFile::fake()->create('notes.txt', 10, 'text/plain')],
|
||||
])
|
||||
->assertSessionHasErrors(['audio.0']);
|
||||
Livewire::test(UploadRecordings::class)
|
||||
->set('audio', [UploadedFile::fake()->create('notes.txt', 10, 'text/plain')])
|
||||
->assertHasErrors(['audio.0']);
|
||||
}
|
||||
|
||||
public function test_user_can_queue_local_transcription(): void
|
||||
@@ -173,8 +168,8 @@ 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))
|
||||
->assertRedirect();
|
||||
Livewire::test(Show::class, ['recording' => $recording])
|
||||
->call('startTranscription');
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('local', $recording->transcription_driver);
|
||||
@@ -332,8 +327,8 @@ class RecordingUploadTest extends TestCase
|
||||
'updated_at' => now()->subMinutes(10),
|
||||
]);
|
||||
|
||||
$this->post(route('recordings.transcribe', $recording))
|
||||
->assertRedirect();
|
||||
Livewire::test(Show::class, ['recording' => $recording])
|
||||
->call('startTranscription');
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('local', $recording->transcription_driver);
|
||||
@@ -355,9 +350,8 @@ class RecordingUploadTest extends TestCase
|
||||
'transcription_started_at' => now(),
|
||||
]);
|
||||
|
||||
$this->post(route('recordings.transcribe.cancel', $recording))
|
||||
->assertRedirect()
|
||||
->assertSessionHas('success');
|
||||
Livewire::test(Show::class, ['recording' => $recording])
|
||||
->call('cancelTranscription');
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('cancelled', $recording->transcription_status);
|
||||
@@ -380,9 +374,8 @@ class RecordingUploadTest extends TestCase
|
||||
'transcription_started_at' => now()->subMinute(),
|
||||
]);
|
||||
|
||||
$this->post(route('recordings.transcribe', $recording))
|
||||
->assertRedirect()
|
||||
->assertSessionHas('success');
|
||||
Livewire::test(Show::class, ['recording' => $recording])
|
||||
->call('startTranscription');
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('local', $recording->transcription_driver);
|
||||
@@ -464,8 +457,8 @@ class RecordingUploadTest extends TestCase
|
||||
'transcribed_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
$this->post(route('recordings.transcribe', $recording))
|
||||
->assertRedirect();
|
||||
Livewire::test(Show::class, ['recording' => $recording])
|
||||
->call('startTranscription');
|
||||
|
||||
$recording->refresh();
|
||||
$this->assertSame('Old transcript text.', $recording->transcript);
|
||||
@@ -497,10 +490,8 @@ class RecordingUploadTest extends TestCase
|
||||
'transcript' => 'Finished text',
|
||||
]);
|
||||
|
||||
$this->from(route('recordings.index'))
|
||||
->post(route('recordings.transcribe-pending'))
|
||||
->assertRedirect(route('recordings.index'))
|
||||
->assertSessionHas('success');
|
||||
Livewire::test(Index::class)
|
||||
->call('queuePending');
|
||||
|
||||
Bus::assertDispatched(TranscribeRecording::class, 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user