Current state with latest updates
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Jobs\GenerateFeaturedArtworkThumbnailsJob;
|
||||
use App\Models\Artwork;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
function makeAuditableArtwork(array $attributes = []): Artwork
|
||||
{
|
||||
return Artwork::factory()->create(array_merge([
|
||||
'user_id' => User::factory()->create()->id,
|
||||
'hash' => str_repeat('a', 64),
|
||||
'file_ext' => 'png',
|
||||
'thumb_ext' => 'webp',
|
||||
], $attributes));
|
||||
}
|
||||
|
||||
test('null featured_thumbnail_variants_json means not audited yet', function () {
|
||||
$artwork = makeAuditableArtwork();
|
||||
|
||||
expect($artwork->featured_thumbnail_variants_json)->toBeNull()
|
||||
->and($artwork->featuredThumbnailAuditState())->toBe(['status' => 'not_audited', 'variants' => []])
|
||||
->and($artwork->hasFeaturedThumbnail())->toBeFalse()
|
||||
->and($artwork->hasFeaturedThumbnail('desktop'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('empty array means audited with no featured variants available', function () {
|
||||
$artwork = makeAuditableArtwork();
|
||||
$artwork->forceFill([
|
||||
'featured_thumbnail_variants_json' => [],
|
||||
'featured_thumbnails_checked_at' => now(),
|
||||
])->saveQuietly();
|
||||
|
||||
$fresh = $artwork->fresh();
|
||||
|
||||
expect($fresh->featured_thumbnail_variants_json)->toBe([])
|
||||
->and($fresh->featuredThumbnailAuditState())->toBe(['status' => 'no_variants', 'variants' => []])
|
||||
->and($fresh->hasFeaturedThumbnail())->toBeFalse();
|
||||
});
|
||||
|
||||
test('a populated array means audited with those variants known to be available', function () {
|
||||
$artwork = makeAuditableArtwork();
|
||||
$artwork->forceFill([
|
||||
'featured_thumbnail_variants_json' => ['desktop', 'desktop_xl'],
|
||||
'featured_thumbnails_checked_at' => now(),
|
||||
])->saveQuietly();
|
||||
|
||||
$fresh = $artwork->fresh();
|
||||
|
||||
expect($fresh->featuredThumbnailAuditState())->toBe(['status' => 'available', 'variants' => ['desktop', 'desktop_xl']])
|
||||
->and($fresh->hasFeaturedThumbnail('desktop'))->toBeTrue()
|
||||
->and($fresh->hasFeaturedThumbnail('desktop_xl'))->toBeTrue()
|
||||
->and($fresh->hasFeaturedThumbnail('mobile'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('malformed json in the column is treated as not audited rather than throwing', function () {
|
||||
$artwork = makeAuditableArtwork();
|
||||
|
||||
// Bypass the array cast to write a raw, non-JSON-array value directly, simulating
|
||||
// legacy or corrupted data that predates this column's introduction.
|
||||
DB::table('artworks')->where('id', $artwork->id)->update([
|
||||
'featured_thumbnail_variants_json' => '"not-an-array"',
|
||||
]);
|
||||
|
||||
$fresh = $artwork->fresh();
|
||||
|
||||
expect($fresh->featuredThumbnailAuditState())->toBe(['status' => 'not_audited', 'variants' => []])
|
||||
->and($fresh->hasFeaturedThumbnail())->toBeFalse();
|
||||
});
|
||||
|
||||
test('non-string entries in the variants array are ignored rather than matched', function () {
|
||||
$artwork = makeAuditableArtwork();
|
||||
|
||||
DB::table('artworks')->where('id', $artwork->id)->update([
|
||||
'featured_thumbnail_variants_json' => json_encode(['desktop', 42, null, ['nested' => true]]),
|
||||
]);
|
||||
|
||||
$fresh = $artwork->fresh();
|
||||
|
||||
expect($fresh->featuredThumbnailAuditState())->toBe(['status' => 'available', 'variants' => ['desktop']])
|
||||
->and($fresh->hasFeaturedThumbnail('desktop'))->toBeTrue()
|
||||
->and($fresh->hasFeaturedThumbnail('tablet'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('an artwork without a hash never reports a featured thumbnail regardless of audit state', function () {
|
||||
$artwork = makeAuditableArtwork(['hash' => null, 'file_ext' => null]);
|
||||
$artwork->forceFill([
|
||||
'featured_thumbnail_variants_json' => ['desktop'],
|
||||
'featured_thumbnails_checked_at' => now(),
|
||||
])->saveQuietly();
|
||||
|
||||
expect($artwork->fresh()->hasFeaturedThumbnail('desktop'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('changing an artwork hash resets stale featured thumbnail audit state and queues regeneration for featured artworks', function () {
|
||||
Queue::fake();
|
||||
|
||||
$artwork = makeAuditableArtwork([
|
||||
'hash' => str_repeat('b', 64),
|
||||
'is_public' => true,
|
||||
'is_approved' => true,
|
||||
'published_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
$artwork->forceFill([
|
||||
'featured_thumbnail_variants_json' => ['desktop', 'desktop_xl'],
|
||||
'featured_thumbnails_checked_at' => now(),
|
||||
])->saveQuietly();
|
||||
|
||||
DB::table('artwork_features')->insert([
|
||||
'artwork_id' => $artwork->id,
|
||||
'featured_at' => now()->subHour(),
|
||||
'expires_at' => null,
|
||||
'priority' => 500,
|
||||
'label' => null,
|
||||
'note' => null,
|
||||
'is_active' => true,
|
||||
'created_by' => null,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
|
||||
// Old hash reported 2 available variants — that state is now stale because the
|
||||
// object paths it referred to were computed from the old hash.
|
||||
expect($artwork->fresh()->hasFeaturedThumbnail('desktop'))->toBeTrue();
|
||||
|
||||
$artwork->hash = str_repeat('c', 64);
|
||||
$artwork->save();
|
||||
|
||||
$fresh = $artwork->fresh();
|
||||
|
||||
expect($fresh->featured_thumbnail_variants_json)->toBeNull()
|
||||
->and($fresh->featured_thumbnails_checked_at)->toBeNull()
|
||||
->and($fresh->hasFeaturedThumbnail('desktop'))->toBeFalse();
|
||||
|
||||
Queue::assertPushed(GenerateFeaturedArtworkThumbnailsJob::class);
|
||||
});
|
||||
|
||||
test('changing hash on an artwork with no active feature row does not queue regeneration', function () {
|
||||
Queue::fake();
|
||||
|
||||
$artwork = makeAuditableArtwork(['hash' => str_repeat('d', 64)]);
|
||||
$artwork->forceFill([
|
||||
'featured_thumbnail_variants_json' => ['desktop'],
|
||||
'featured_thumbnails_checked_at' => now(),
|
||||
])->saveQuietly();
|
||||
|
||||
$artwork->hash = str_repeat('e', 64);
|
||||
$artwork->save();
|
||||
|
||||
expect($artwork->fresh()->featured_thumbnail_variants_json)->toBeNull();
|
||||
Queue::assertNotPushed(GenerateFeaturedArtworkThumbnailsJob::class);
|
||||
});
|
||||
Reference in New Issue
Block a user