id.'/'.uniqid().'.pdf'; Storage::disk('local')->put($path, 'file-contents'); return Certificate::factory()->for($user)->create(['file_path' => $path]); } test('creating a share stores it and reveals the link and password', function () { $user = User::factory()->create(); $certificate = sharableCertificate($user); $this->actingAs($user); $component = Livewire::test('pages::certificates.index') ->set('selected', [$certificate->id]) ->set('shareExpiresInDays', 7) ->set('sharePasswordProtect', true) ->call('share') ->assertHasNoErrors(); $share = Share::first(); expect($share)->not->toBeNull() ->and($share->certificates()->count())->toBe(1) ->and($share->password)->toHaveLength(12) ->and($share->expires_at->isSameDay(now()->addDays(7)))->toBeTrue() ->and($component->get('createdShareUrl'))->toBe($share->url()) ->and($component->get('createdSharePassword'))->toBe($share->password); Mail::assertNothingSent(); }); test('a share without password protection stores no password', function () { $user = User::factory()->create(); $certificate = sharableCertificate($user); $this->actingAs($user); Livewire::test('pages::certificates.index') ->set('selected', [$certificate->id]) ->set('sharePasswordProtect', false) ->call('share') ->assertHasNoErrors(); expect(Share::first()->password)->toBeNull(); }); test('providing a recipient email sends the share link by mail', 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') ->call('share') ->assertHasNoErrors(); expect(Share::first()->recipient_email)->toBe('friend@example.com'); Mail::assertSent(ShareCreatedMail::class, fn ($mail) => $mail->hasTo('friend@example.com')); }); test('sharing requires a selection', function () { $this->actingAs(User::factory()->create()); Livewire::test('pages::certificates.index') ->set('selected', []) ->call('share') ->assertHasErrors(['selected']); expect(Share::count())->toBe(0); }); test('certificates from another user cannot be shared', function () { $owner = User::factory()->create(); $certificate = sharableCertificate($owner); $this->actingAs(User::factory()->create()); Livewire::test('pages::certificates.index') ->set('selected', [$certificate->id]) ->call('share') ->assertHasErrors(['selected']); expect(Share::withoutGlobalScopes()->count())->toBe(0); }); test('emailing shares 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(); });