Files
SkinbaseNova/tests/Feature/HomePageTest.php

122 lines
3.8 KiB
PHP

<?php
use App\Models\User;
use App\Services\ArtworkService;
use Illuminate\Pagination\LengthAwarePaginator;
/** Return an empty LengthAwarePaginator with the given path. */
function emptyPaginator(string $path = '/'): LengthAwarePaginator
{
return (new LengthAwarePaginator(collect(), 0, 20, 1))->setPath($path);
}
beforeEach(function () {
// Swap ArtworkService so tests need no database
$this->artworksMock = \Mockery::mock(ArtworkService::class);
$this->artworksMock->shouldReceive('getFeaturedArtworks')->andReturn(emptyPaginator('/'))->byDefault();
$this->artworksMock->shouldReceive('getFeaturedArtworkWinner')->andReturn(null)->byDefault();
$this->artworksMock->shouldReceive('getLatestArtworks')->andReturn(collect())->byDefault();
$this->app->instance(ArtworkService::class, $this->artworksMock);
});
it('renders the home page successfully', function () {
$this->get('/')
->assertStatus(200);
});
it('renders the home page with grid=v2 without errors', function () {
$this->get('/?grid=v2')
->assertStatus(200);
});
it('home page contains the gallery section', function () {
$this->get('/')
->assertStatus(200)
->assertSee('<main', false)
->assertDontSee('id="homepage-root"', false)
->assertDontSee('id="homepage-props"', false);
});
it('guest home page sends public cache headers', function () {
$response = $this->get('/')
->assertOk()
->assertHeader('Cache-Control');
$cacheControl = (string) $response->headers->get('Cache-Control');
expect($cacheControl)
->toContain('public')
->toContain('max-age=60')
->toContain('s-maxage=300')
->toContain('stale-while-revalidate=600');
});
it('authenticated home page sends private cache headers', function () {
$user = User::factory()->create();
$response = $this->actingAs($user)
->get('/')
->assertOk()
->assertHeader('Cache-Control');
expect((string) $response->headers->get('Cache-Control'))
->toContain('private')
->toContain('no-store');
});
it('home page includes a canonical link tag', function () {
$this->get('/')
->assertStatus(200)
->assertSee('rel="canonical"', false);
});
it('home page renders crawlable artwork links without inertia payload markup', function () {
$html = $this->get('/')
->assertOk()
->getContent();
expect($html)
->not->toContain('data-page=')
->not->toContain('homepage-props')
->toContain('/discover/trending');
});
it('home page emits unified SEO tags and structured data', function () {
$html = $this->get('/')
->assertStatus(200)
->getContent();
expect($html)
->toContain('name="description"')
->toContain('property="og:title"')
->toContain('name="twitter:card"')
->toContain('application/ld+json')
->toContain('WebSite');
});
it('home page exposes digital art in the explore navigation', function () {
$html = $this->get('/')
->assertStatus(200)
->getContent();
expect($html)
->toContain('href="/digital-art"')
->toContain('Digital Art');
});
it('home page with ?page=2 renders without errors', function () {
// getLatestArtworks() returns a plain Collection (no pagination),
// so seoNext/seoPrev for home are always null — but the page must still render cleanly.
$this->get('/?page=2')
->assertStatus(200)
->assertSee('rel="canonical"', false);
});
it('home page does not throw undefined variable errors', function () {
// If any Blade variable is undefined an exception is thrown → non-200 status
// This test explicitly guards against regressions on $gridV2 / $seoCanonical
expect(
fn () => $this->get('/')->assertStatus(200)
)->not->toThrow(\ErrorException::class);
});