Files
SealShare/tests/Screenshots/DemoData.php
T
Andreas Reinhold / reiniandClaude Opus 5 e49bdf3eb3 Take the website's screenshots with one command
composer screenshots runs Pest browser tests in tests/Screenshots, outside
every test suite: fixed demo data under a frozen clock, desktop (MacBook
14, 2x) and phone (iPhone 15 Pro, 3x) in light and dark, each capture
published at once as WebP at two widths into website/img/screenshots.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
2026-09-13 12:30:53 +02:00

90 lines
4.3 KiB
PHP

<?php
namespace Tests\Screenshots;
use App\Models\Share;
use App\Models\User;
use App\Services\ShareService;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
/**
* The shares and the admin every screenshot shows. Names, sizes, tokens, counts and dates are fixed
* (with the clock frozen by the caller), so a run only produces different images when the interface
* changed. Files go through ShareService, so they exist encrypted on the faked `shares` disk.
*/
final class DemoData
{
/** The share a customer receives: link, QR code and download page. */
public const DELIVERY_TOKEN = 'hG7kP2mXq9LrT4vB';
/** The password-protected share the phone's password prompt belongs to. */
public const PROTECTED_TOKEN = 'Wn3sD8fJ5cYa1ZeQ';
public const PROTECTED_PASSWORD = 'autumn-harbour-42';
public static function admin(): User
{
return User::factory()->admin()->create([
'name' => 'Alex Morgan',
'email' => 'alex.morgan@example.com',
]);
}
/**
* Eight shares of different ages, sizes and states: one expired, two password-protected, some
* with a download limit, some never expiring.
*/
public static function shares(): void
{
$shares = [
['token' => self::DELIVERY_TOKEN, 'daysAgo' => 0, 'expiresAfterDays' => 7, 'downloads' => 3, 'options' => [],
'files' => ['Q3 Report.pdf' => 2400, 'Contract 2026.pdf' => 380, 'Product photos/hero-shot.jpg' => 4800, 'Product photos/detail.jpg' => 3900]],
['token' => self::PROTECTED_TOKEN, 'daysAgo' => 1, 'expiresAfterDays' => 3, 'downloads' => 1, 'options' => ['password' => self::PROTECTED_PASSWORD, 'max_downloads' => 3],
'files' => ['Payroll September.xlsx' => 210, 'Tax statement 2025.pdf' => 640]],
['token' => 'Rt5uV6wX7yZ8aB9c', 'daysAgo' => 2, 'expiresAfterDays' => 30, 'downloads' => 7, 'options' => ['max_downloads' => 10],
'files' => ['Brand guidelines.pdf' => 8600]],
['token' => 'Kc2dE3fG4hJ5kL6m', 'daysAgo' => 5, 'expiresAfterDays' => 14, 'downloads' => 2, 'options' => [],
'files' => ['Site plan rev C.dwg' => 12400, 'Site plan rev C.pdf' => 3100]],
['token' => 'Np7qR8sT9uV1wX2y', 'daysAgo' => 9, 'expiresAfterDays' => null, 'downloads' => 0, 'options' => ['password' => 'demo-interview'],
'files' => ['Interview recording.m4a' => 18300]],
['token' => 'Zb4cD5eF6gH7jK8L', 'daysAgo' => 14, 'expiresAfterDays' => 30, 'downloads' => 0, 'options' => ['max_downloads' => 1],
'files' => ['Invoice 2026-0412.pdf' => 95]],
['token' => 'Mq1rS2tU3vW4xY5z', 'daysAgo' => 21, 'expiresAfterDays' => null, 'downloads' => 4, 'options' => [],
'files' => ['Onboarding/Welcome.pdf' => 520, 'Onboarding/Handbook.pdf' => 2900, 'Onboarding/IT checklist.docx' => 130]],
['token' => 'Ae6fG7hJ8kL9mN1p', 'daysAgo' => 40, 'expiresAfterDays' => 10, 'downloads' => 12, 'options' => [],
'files' => ['Event photos.zip' => 15700]],
];
foreach ($shares as $share) {
self::share(...$share);
}
}
/**
* @param array{password?: string, max_downloads?: int} $options
* @param array<string, int> $files relative path => size in kilobytes
*/
private static function share(string $token, int $daysAgo, ?int $expiresAfterDays, int $downloads, array $options, array $files): void
{
$createdAt = Carbon::now()->subDays($daysAgo)->subHours(2);
Str::createRandomStringsUsing(fn (): string => $token);
try {
$share = app(ShareService::class)->createShare(
collect($files)->map(fn (int $kilobytes, string $path): array => [
'file' => UploadedFile::fake()->create(basename($path), $kilobytes),
'relativePath' => str_contains($path, '/') ? $path : null,
])->values()->all(),
[...$options, 'expires_at' => $expiresAfterDays === null ? null : $createdAt->copy()->addDays($expiresAfterDays)],
);
} finally {
Str::createRandomStringsNormally();
}
$share->forceFill(['download_count' => $downloads, 'created_at' => $createdAt, 'updated_at' => $createdAt])->save();
}
}