id.'/'.uniqid().'.pdf'; Storage::disk('local')->put($path, 'file-contents'); return Certificate::factory()->for($user)->create(['file_path' => $path]); } test('sharing by secure link emails the recipient', function () { $user = User::factory()->create(); $certificate = sharableCertificate($user); $this->actingAs($user); Livewire::test('pages::certificates.index') ->set('selected', [$certificate->id]) ->set('shareEmail', 'friend@example.com') ->set('shareMethod', 'link') ->call('share') ->assertHasNoErrors(); Mail::assertSent(SharedCertificateLinksMail::class, fn ($mail) => $mail->hasTo('friend@example.com')); }); test('sharing by zip emails an attachment and reveals a password', function () { $user = User::factory()->create(); $certificate = sharableCertificate($user); $this->actingAs($user); $component = Livewire::test('pages::certificates.index') ->set('selected', [$certificate->id]) ->set('shareEmail', 'friend@example.com') ->set('shareMethod', 'zip') ->call('share') ->assertHasNoErrors(); expect($component->get('sharePassword'))->toHaveLength(12); Mail::assertSent(SharedCertificatesMail::class, fn ($mail) => $mail->hasTo('friend@example.com')); }); test('sharing requires a recipient and a selection', function () { $this->actingAs(User::factory()->create()); Livewire::test('pages::certificates.index') ->set('shareEmail', '') ->set('selected', []) ->call('share') ->assertHasErrors(['shareEmail', 'selected']); Mail::assertNothingSent(); }); test('sharing is rate limited', function () { $user = User::factory()->create(); $certificate = sharableCertificate($user); $this->actingAs($user); for ($i = 0; $i < 10; $i++) { RateLimiter::hit('share-certificates:'.$user->id, 3600); } Livewire::test('pages::certificates.index') ->set('selected', [$certificate->id]) ->set('shareEmail', 'friend@example.com') ->call('share') ->assertHasErrors(['shareEmail']); Mail::assertNothingSent(); }); test('a valid signed link streams the file to an unauthenticated recipient', function () { $user = User::factory()->create(); $certificate = sharableCertificate($user); $url = URL::temporarySignedRoute('shared.certificate', now()->addHours(48), ['certificate' => $certificate->id]); $this->get($url)->assertOk(); }); test('a tampered signed link is rejected', function () { $user = User::factory()->create(); $certificate = sharableCertificate($user); $this->get(route('shared.certificate', $certificate))->assertForbidden(); });