gallery fix
This commit is contained in:
@@ -7,13 +7,134 @@ use App\Models\Category;
|
||||
use App\Models\ContentType;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Str;
|
||||
use Tests\TestCase;
|
||||
|
||||
class BrowseApiTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_web_browse_renders_canonical_and_rel_prev_next_for_paginated_pages(): void
|
||||
{
|
||||
$user = User::factory()->create(['name' => 'Seo Author']);
|
||||
$contentType = ContentType::create([
|
||||
'name' => 'Skins',
|
||||
'slug' => 'skins',
|
||||
'description' => 'Skins content type',
|
||||
]);
|
||||
|
||||
$category = Category::create([
|
||||
'content_type_id' => $contentType->id,
|
||||
'name' => 'Classic',
|
||||
'slug' => 'classic',
|
||||
'description' => 'Classic skins',
|
||||
'is_active' => true,
|
||||
'sort_order' => 1,
|
||||
]);
|
||||
|
||||
for ($i = 1; $i <= 25; $i++) {
|
||||
$artwork = Artwork::factory()
|
||||
->for($user)
|
||||
->create([
|
||||
'title' => 'Seo Item ' . $i,
|
||||
'slug' => 'seo-item-' . $i,
|
||||
'published_at' => now()->subMinutes($i),
|
||||
]);
|
||||
$artwork->categories()->attach($category->id);
|
||||
}
|
||||
|
||||
$response = $this->get('/browse?limit=12&grid=v2');
|
||||
$response->assertOk();
|
||||
|
||||
$html = $response->getContent();
|
||||
$this->assertNotFalse($html);
|
||||
$this->assertStringContainsString('<meta name="robots" content="index,follow" />', $html);
|
||||
$this->assertMatchesRegularExpression('/<link rel="canonical" href="[^"]*\/browse\?limit=12"\s*\/>/i', $html);
|
||||
preg_match('/<link rel="canonical" href="([^"]+)"\s*\/>/i', $html, $canonicalMatches);
|
||||
$this->assertArrayHasKey(1, $canonicalMatches);
|
||||
$canonicalUrl = html_entity_decode((string) $canonicalMatches[1], ENT_QUOTES);
|
||||
$this->assertStringNotContainsString('grid=v2', $canonicalUrl);
|
||||
|
||||
$this->assertMatchesRegularExpression('/<link rel="next" href="([^"]+)"\s*\/>/i', $html);
|
||||
preg_match('/<link rel="next" href="([^"]+)"\s*\/>/i', $html, $nextMatches);
|
||||
$this->assertArrayHasKey(1, $nextMatches);
|
||||
$nextUrl = html_entity_decode((string) $nextMatches[1], ENT_QUOTES);
|
||||
$this->assertStringContainsString('cursor=', $nextUrl);
|
||||
$this->assertStringNotContainsString('grid=v2', $nextUrl);
|
||||
|
||||
$secondPage = $this->get($nextUrl);
|
||||
$secondPage->assertOk();
|
||||
$secondHtml = $secondPage->getContent();
|
||||
$this->assertNotFalse($secondHtml);
|
||||
$this->assertMatchesRegularExpression('/<link rel="prev" href="([^"]+)"\s*\/>/i', $secondHtml);
|
||||
preg_match('/<link rel="prev" href="([^"]+)"\s*\/>/i', $secondHtml, $prevMatches);
|
||||
$this->assertArrayHasKey(1, $prevMatches);
|
||||
$prevUrl = html_entity_decode((string) $prevMatches[1], ENT_QUOTES);
|
||||
$this->assertStringNotContainsString('grid=v2', $prevUrl);
|
||||
$this->assertMatchesRegularExpression('/<link rel="canonical" href="[^"]*\/browse\?[^\"]*cursor=/i', $secondHtml);
|
||||
preg_match('/<link rel="canonical" href="([^"]+)"\s*\/>/i', $secondHtml, $secondCanonicalMatches);
|
||||
$this->assertArrayHasKey(1, $secondCanonicalMatches);
|
||||
$secondCanonicalUrl = html_entity_decode((string) $secondCanonicalMatches[1], ENT_QUOTES);
|
||||
$this->assertStringNotContainsString('grid=v2', $secondCanonicalUrl);
|
||||
|
||||
$pageOne = $this->get('/browse?limit=12&page=1&grid=v2');
|
||||
$pageOne->assertOk();
|
||||
$pageOneHtml = $pageOne->getContent();
|
||||
$this->assertNotFalse($pageOneHtml);
|
||||
$this->assertMatchesRegularExpression('/<link rel="canonical" href="[^"]*\/browse\?limit=12"\s*\/>/i', $pageOneHtml);
|
||||
preg_match('/<link rel="canonical" href="([^"]+)"\s*\/>/i', $pageOneHtml, $pageOneCanonicalMatches);
|
||||
$this->assertArrayHasKey(1, $pageOneCanonicalMatches);
|
||||
$pageOneCanonicalUrl = html_entity_decode((string) $pageOneCanonicalMatches[1], ENT_QUOTES);
|
||||
$this->assertStringNotContainsString('page=1', $pageOneCanonicalUrl);
|
||||
}
|
||||
|
||||
public function test_api_browse_supports_limit_and_cursor_pagination(): void
|
||||
{
|
||||
$user = User::factory()->create(['name' => 'Cursor Author']);
|
||||
|
||||
$contentType = ContentType::create([
|
||||
'name' => 'Skins',
|
||||
'slug' => 'skins',
|
||||
'description' => 'Skins content type',
|
||||
]);
|
||||
|
||||
$category = Category::create([
|
||||
'content_type_id' => $contentType->id,
|
||||
'name' => 'Winamp',
|
||||
'slug' => 'winamp',
|
||||
'description' => 'Winamp skins',
|
||||
'is_active' => true,
|
||||
'sort_order' => 1,
|
||||
]);
|
||||
|
||||
for ($i = 1; $i <= 6; $i++) {
|
||||
$artwork = Artwork::factory()
|
||||
->for($user)
|
||||
->create([
|
||||
'title' => 'Cursor Item ' . $i,
|
||||
'slug' => 'cursor-item-' . $i,
|
||||
'published_at' => now()->subMinutes($i),
|
||||
]);
|
||||
|
||||
$artwork->categories()->attach($category->id);
|
||||
}
|
||||
|
||||
$first = $this->getJson('/api/v1/browse?limit=2');
|
||||
$first->assertOk();
|
||||
$first->assertJsonCount(2, 'data');
|
||||
|
||||
$nextCursor = (string) data_get($first->json(), 'links.next', '');
|
||||
$this->assertNotEmpty($nextCursor);
|
||||
$this->assertStringContainsString('cursor=', $nextCursor);
|
||||
|
||||
$second = $this->getJson($nextCursor);
|
||||
$second->assertOk();
|
||||
$second->assertJsonCount(2, 'data');
|
||||
|
||||
$firstFirstSlug = data_get($first->json(), 'data.0.slug');
|
||||
$secondFirstSlug = data_get($second->json(), 'data.0.slug');
|
||||
$this->assertNotSame($firstFirstSlug, $secondFirstSlug);
|
||||
}
|
||||
|
||||
public function test_api_browse_returns_public_artworks(): void
|
||||
{
|
||||
$user = User::factory()->create(['name' => 'Author One']);
|
||||
@@ -82,5 +203,14 @@ class BrowseApiTest extends TestCase
|
||||
$response->assertOk();
|
||||
$response->assertSee('Forest Light');
|
||||
$response->assertSee('Author Two');
|
||||
|
||||
$html = $response->getContent();
|
||||
$this->assertNotFalse($html);
|
||||
$this->assertStringContainsString('itemprop="thumbnailUrl"', $html);
|
||||
// First card (index 0) is eager-loaded with fetchpriority=high — no blur-preview
|
||||
$this->assertStringContainsString('loading="eager"', $html);
|
||||
$this->assertStringContainsString('decoding="sync"', $html);
|
||||
$this->assertStringContainsString('fetchpriority="high"', $html);
|
||||
$this->assertMatchesRegularExpression('/<img[^>]*loading="eager"[^>]*width="\d+"[^>]*height="\d+"/i', $html);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,11 +47,19 @@ class DashboardFavoritesTest extends TestCase
|
||||
|
||||
DB::table($favTable)->insert($insert);
|
||||
|
||||
$this->actingAs($user)
|
||||
$response = $this->actingAs($user)
|
||||
->get(route('dashboard.favorites'))
|
||||
->assertOk()
|
||||
->assertSee('Fav Artwork');
|
||||
|
||||
$html = $response->getContent();
|
||||
$this->assertNotFalse($html);
|
||||
$this->assertStringContainsString('itemprop="thumbnailUrl"', $html);
|
||||
$this->assertStringContainsString('data-blur-preview', $html);
|
||||
$this->assertStringContainsString('loading="lazy"', $html);
|
||||
$this->assertStringContainsString('decoding="async"', $html);
|
||||
$this->assertMatchesRegularExpression('/<img[^>]*data-blur-preview[^>]*width="\d+"[^>]*height="\d+"/i', $html);
|
||||
|
||||
$this->actingAs($user)
|
||||
->delete(route('dashboard.favorites.destroy', ['artwork' => $art->id]))
|
||||
->assertRedirect(route('dashboard.favorites'));
|
||||
|
||||
Reference in New Issue
Block a user