user = User::factory()->create(); $this->actingAs($this->user); } public function test_duplicate_content_hash_is_skipped_on_upload(): void { Storage::fake('local'); Bus::fake(); $first = UploadedFile::fake()->createWithContent('meeting.mp3', 'identical-audio-bytes'); $duplicate = UploadedFile::fake()->createWithContent('meeting-copy.mp3', 'identical-audio-bytes'); Livewire::test(UploadRecordings::class) ->set('audio', [$first]) ->assertRedirect(); $this->assertSame(1, Recording::query()->count()); Bus::assertDispatched(TranscribeRecording::class, 1); Livewire::test(UploadRecordings::class) ->set('audio', [$duplicate]) ->assertRedirect(route('recordings.create')) ->assertSessionHas('error'); $this->assertSame(1, Recording::query()->count()); Bus::assertDispatched(TranscribeRecording::class, 1); } public function test_batch_upload_skips_duplicate_content_within_request(): void { Storage::fake('local'); Bus::fake(); $one = UploadedFile::fake()->createWithContent('one.mp3', 'same-bytes'); $two = UploadedFile::fake()->createWithContent('two.mp3', 'same-bytes'); $three = UploadedFile::fake()->createWithContent('three.mp3', 'different-bytes'); Livewire::test(UploadRecordings::class) ->set('audio', [$one, $two, $three]) ->assertRedirect(route('recordings.index')) ->assertSessionHas('success'); $this->assertStringContainsString('Skipped 1 duplicate', session('success')); $this->assertSame(2, Recording::query()->count()); Bus::assertDispatched(TranscribeRecording::class, 2); } public function test_upload_page_mentions_duplicate_skipping(): void { Recording::query()->create([ 'user_id' => $this->user->id, 'title' => 'Existing', 'original_filename' => 'note.mp3', 'file_path' => 'recordings/note.mp3', 'file_size_bytes' => 2048, 'content_hash' => str_repeat('a', 64), 'transcription_status' => 'done', ]); $this->get(route('recordings.create')) ->assertOk() ->assertSeeLivewire('upload-recordings') ->assertSee('Duplicate files', false); } public function test_duplicate_filename_and_size_is_skipped_without_content_hash(): void { Storage::fake('local'); Bus::fake(); Recording::query()->create([ 'user_id' => $this->user->id, 'title' => 'Legacy', 'original_filename' => 'legacy.mp3', 'file_path' => 'recordings/legacy.mp3', 'file_size_bytes' => strlen('legacy-audio'), 'content_hash' => null, 'transcription_status' => 'done', ]); Livewire::test(UploadRecordings::class) ->set('audio', [UploadedFile::fake()->createWithContent('legacy.mp3', 'legacy-audio')]) ->assertRedirect(route('recordings.create')) ->assertSessionHas('error'); $this->assertSame(1, Recording::query()->count()); Bus::assertNothingDispatched(); } public function test_stored_recording_persists_content_hash(): void { Storage::fake('local'); Bus::fake(); $file = UploadedFile::fake()->createWithContent('hash-me.mp3', 'payload-for-hash'); Livewire::test(UploadRecordings::class) ->set('audio', [$file]) ->assertRedirect(); $recording = Recording::query()->first(); $this->assertNotNull($recording); $this->assertSame(hash('sha256', 'payload-for-hash'), $recording->content_hash); } }