create(); $path = 'certificates/'.$user->id.'/'.uniqid().'.pdf'; Storage::disk('local')->put($path, 'file-contents'); $certificate = Certificate::factory()->for($user)->create([ 'title' => 'Forklift License', 'file_path' => $path, ]); $share = Share::factory()->for($user)->state($shareState)->create(); $share->certificates()->attach($certificate); return $share; } test('an active share page lists the certificates for an unauthenticated visitor', function () { $share = shareWithCertificate(); $this->get(route('shared.show', $share->token)) ->assertOk() ->assertSee('Forklift License') ->assertSee(__('Download all as ZIP')); }); test('opening the page is recorded on the share', function () { $share = shareWithCertificate(); $this->get(route('shared.show', $share->token))->assertOk(); $this->get(route('shared.show', $share->token))->assertOk(); $share->refresh(); expect($share->access_count)->toBe(2) ->and($share->last_accessed_at)->not->toBeNull(); }); test('an unknown token is not found', function () { $this->get(route('shared.show', 'nonexistent-token'))->assertNotFound(); }); test('an expired share renders the gone page', function () { $share = shareWithCertificate(['expires_at' => now()->subDay()]); $this->get(route('shared.show', $share->token)) ->assertGone() ->assertSee(__('This share is no longer available')); }); test('a revoked share renders the gone page', function () { $share = shareWithCertificate(['revoked_at' => now()->subHour()]); $this->get(route('shared.show', $share->token))->assertGone(); }); test('a password protected share asks for the password first', function () { $share = shareWithCertificate(['password' => 'top-secret-123']); $this->get(route('shared.show', $share->token)) ->assertOk() ->assertSee(__('This share is password protected')) ->assertDontSee('Forklift License'); }); test('the correct password unlocks the share for the session', function () { $share = shareWithCertificate(['password' => 'top-secret-123']); $this->post(route('shared.unlock', $share->token), ['password' => 'top-secret-123']) ->assertRedirect(route('shared.show', $share->token)); $this->get(route('shared.show', $share->token)) ->assertOk() ->assertSee('Forklift License'); }); test('a wrong password does not unlock the share', function () { $share = shareWithCertificate(['password' => 'top-secret-123']); $this->post(route('shared.unlock', $share->token), ['password' => 'wrong']) ->assertSessionHasErrors('password'); $this->get(route('shared.show', $share->token))->assertDontSee('Forklift License'); }); test('a certificate in the share can be downloaded', function () { $share = shareWithCertificate(); $certificate = $share->certificates->first(); $this->get(route('shared.certificate', ['share' => $share->token, 'certificate' => $certificate->id])) ->assertOk() ->assertDownload('Forklift License.pdf'); }); test('a certificate outside the share cannot be downloaded through it', function () { $share = shareWithCertificate(); $other = Certificate::factory()->create(['file_path' => 'certificates/other.pdf']); $this->get(route('shared.certificate', ['share' => $share->token, 'certificate' => $other->id])) ->assertNotFound(); }); test('downloads are blocked while a password protected share is locked', function () { $share = shareWithCertificate(['password' => 'top-secret-123']); $certificate = $share->certificates->first(); $this->get(route('shared.certificate', ['share' => $share->token, 'certificate' => $certificate->id])) ->assertForbidden(); $this->get(route('shared.zip', $share->token))->assertForbidden(); }); test('downloads are blocked once the share expires', function () { $share = shareWithCertificate(['expires_at' => now()->subDay()]); $certificate = $share->certificates->first(); $this->get(route('shared.certificate', ['share' => $share->token, 'certificate' => $certificate->id])) ->assertGone(); }); test('the zip download returns an archive', function () { $share = shareWithCertificate(); $this->get(route('shared.zip', $share->token)) ->assertOk() ->assertDownload('certificates.zip'); });