Add tests for featured thumbnail generation; apply Pint formatting and related edits
This commit is contained in:
@@ -5,9 +5,16 @@ declare(strict_types=1);
|
||||
use App\Models\User;
|
||||
use Inertia\Testing\AssertableInertia;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use cPad\Plugins\News\Models\NewsArticle;
|
||||
use cPad\Plugins\News\Models\NewsCategory;
|
||||
use cPad\Plugins\News\Models\NewsTag;
|
||||
use App\Models\Artwork;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
function studioNewsCategory(array $attributes = []): NewsCategory
|
||||
{
|
||||
@@ -298,4 +305,124 @@ it('soft deletes a newsroom article from studio', function (): void {
|
||||
$this->assertSoftDeleted('news_articles', [
|
||||
'id' => $article->id,
|
||||
]);
|
||||
});
|
||||
|
||||
it('uploads newsroom cover images with responsive variants and deletes them together', function (): void {
|
||||
Storage::fake('s3');
|
||||
|
||||
config()->set('uploads.object_storage.disk', 's3');
|
||||
config()->set('cdn.files_url', 'https://cdn.skinbase.test');
|
||||
|
||||
$moderator = User::factory()->create([
|
||||
'role' => 'moderator',
|
||||
]);
|
||||
|
||||
$uploadResponse = $this->actingAs($moderator)->postJson(route('api.studio.news.media.upload'), [
|
||||
'image' => UploadedFile::fake()->image('news-cover.jpg', 1600, 900),
|
||||
]);
|
||||
|
||||
$uploadResponse->assertOk();
|
||||
|
||||
$path = (string) $uploadResponse->json('path');
|
||||
$mobileUrl = (string) $uploadResponse->json('mobile_url');
|
||||
$desktopUrl = (string) $uploadResponse->json('desktop_url');
|
||||
$srcset = (string) $uploadResponse->json('srcset');
|
||||
|
||||
expect($path)->toMatch('#^news/covers/[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{64}\.webp$#');
|
||||
expect($mobileUrl)->toBe('https://cdn.skinbase.test/' . preg_replace('#\.webp$#', '-mobile.webp', $path));
|
||||
expect($desktopUrl)->toBe('https://cdn.skinbase.test/' . preg_replace('#\.webp$#', '-desktop.webp', $path));
|
||||
expect($srcset)->toContain($mobileUrl . ' 400w')
|
||||
->toContain($desktopUrl . ' 768w');
|
||||
|
||||
Storage::disk('s3')->assertExists($path);
|
||||
Storage::disk('s3')->assertExists(preg_replace('#\.webp$#', '-mobile.webp', $path));
|
||||
Storage::disk('s3')->assertExists(preg_replace('#\.webp$#', '-desktop.webp', $path));
|
||||
|
||||
$this->actingAs($moderator)
|
||||
->deleteJson(route('api.studio.news.media.destroy'), ['path' => $path])
|
||||
->assertOk();
|
||||
|
||||
Storage::disk('s3')->assertMissing($path);
|
||||
Storage::disk('s3')->assertMissing(preg_replace('#\.webp$#', '-mobile.webp', $path));
|
||||
Storage::disk('s3')->assertMissing(preg_replace('#\.webp$#', '-desktop.webp', $path));
|
||||
});
|
||||
|
||||
it('backfills missing responsive variants for managed newsroom covers', function (): void {
|
||||
Storage::fake('s3');
|
||||
Http::fake([
|
||||
'https://api.cloudflare.com/client/v4/zones/test-zone/purge_cache' => Http::response(['success' => true], 200),
|
||||
]);
|
||||
|
||||
config()->set('uploads.object_storage.disk', 's3');
|
||||
config()->set('cdn.files_url', 'https://cdn.skinbase.test');
|
||||
config()->set('cdn.cloudflare.zone_id', 'test-zone');
|
||||
config()->set('cdn.cloudflare.api_token', 'test-token');
|
||||
|
||||
$author = User::factory()->create();
|
||||
$category = studioNewsCategory();
|
||||
$masterPath = 'news/covers/aa/bb/' . str_repeat('a', 64) . '.webp';
|
||||
|
||||
Storage::disk('s3')->put($masterPath, UploadedFile::fake()->image('source.jpg', 1600, 900)->get());
|
||||
|
||||
NewsArticle::query()->create([
|
||||
'title' => 'Backfill cover variants',
|
||||
'slug' => 'backfill-cover-variants',
|
||||
'excerpt' => 'Backfill test.',
|
||||
'content' => 'Backfill test body.',
|
||||
'author_id' => $author->id,
|
||||
'category_id' => $category->id,
|
||||
'cover_image' => $masterPath,
|
||||
'type' => NewsArticle::TYPE_ANNOUNCEMENT,
|
||||
'status' => 'draft',
|
||||
'editorial_status' => NewsArticle::EDITORIAL_STATUS_DRAFT,
|
||||
]);
|
||||
|
||||
$this->artisan('news:generate-cover-thumbnails')
|
||||
->assertSuccessful()
|
||||
->expectsOutputToContain('generated=1');
|
||||
|
||||
Storage::disk('s3')->assertExists('news/covers/aa/bb/' . str_repeat('a', 64) . '-mobile.webp');
|
||||
Storage::disk('s3')->assertExists('news/covers/aa/bb/' . str_repeat('a', 64) . '-desktop.webp');
|
||||
|
||||
Http::assertNothingSent();
|
||||
|
||||
$this->artisan('news:generate-cover-thumbnails', ['--force' => true])
|
||||
->assertSuccessful()
|
||||
->expectsOutputToContain('generated=1');
|
||||
|
||||
Http::assertSent(function ($request) use ($masterPath): bool {
|
||||
return $request->url() === 'https://api.cloudflare.com/client/v4/zones/test-zone/purge_cache'
|
||||
&& $request->hasHeader('Authorization', 'Bearer test-token')
|
||||
&& $request['files'] === [
|
||||
'https://cdn.skinbase.test/' . preg_replace('#\.webp$#', '-mobile.webp', $masterPath),
|
||||
'https://cdn.skinbase.test/' . preg_replace('#\.webp$#', '-desktop.webp', $masterPath),
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
it('searches news artwork entities without relying on a top-level views column', function (): void {
|
||||
$moderator = User::factory()->create([
|
||||
'role' => 'moderator',
|
||||
]);
|
||||
|
||||
$artwork = Artwork::factory()->create([
|
||||
'title' => 'Entity Search Artwork',
|
||||
'slug' => 'entity-search-artwork',
|
||||
'artwork_status' => 'published',
|
||||
'is_public' => true,
|
||||
'visibility' => Artwork::VISIBILITY_PUBLIC,
|
||||
'is_approved' => true,
|
||||
'published_at' => now()->subDay(),
|
||||
]);
|
||||
|
||||
$this->actingAs($moderator)
|
||||
->getJson(route('studio.news.entity-search', [
|
||||
'type' => 'artwork',
|
||||
'q' => 'Entity Search',
|
||||
]))
|
||||
->assertOk()
|
||||
->assertJsonFragment([
|
||||
'id' => $artwork->id,
|
||||
'title' => 'Entity Search Artwork',
|
||||
]);
|
||||
});
|
||||
Reference in New Issue
Block a user