118 lines
4.2 KiB
PHP
118 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\User;
|
|
use App\Models\Artwork;
|
|
use App\Models\Group;
|
|
use App\Services\ArtworkService;
|
|
use App\Services\HomepageService;
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
beforeEach(function () {
|
|
// Use null Scout driver — Meilisearch calls return empty results gracefully
|
|
config(['scout.driver' => 'null']);
|
|
|
|
// ArtworkService is not final so it can be mocked
|
|
$artworksMock = Mockery::mock(ArtworkService::class);
|
|
$artworksMock->shouldReceive('getFeaturedArtworks')
|
|
->andReturn(new LengthAwarePaginator(collect(), 0, 1))
|
|
->byDefault();
|
|
$artworksMock->shouldReceive('getFeaturedArtworkWinner')
|
|
->andReturn(null)
|
|
->byDefault();
|
|
app()->instance(ArtworkService::class, $artworksMock);
|
|
});
|
|
|
|
// ── Route integration ─────────────────────────────────────────────────────────
|
|
|
|
it('home page renders 200 for guests', function () {
|
|
$this->get('/')->assertStatus(200);
|
|
});
|
|
|
|
it('home page renders 200 for authenticated users', function () {
|
|
$this->actingAs(User::factory()->create())
|
|
->get('/')
|
|
->assertStatus(200);
|
|
});
|
|
|
|
// ── HomepageService section shape ─────────────────────────────────────────────
|
|
|
|
it('guest homepage has expected sections but no from_following', function () {
|
|
$sections = app(HomepageService::class)->all();
|
|
|
|
expect($sections)->toHaveKeys(['hero', 'trending', 'fresh', 'tags', 'creators', 'news']);
|
|
expect($sections)->not->toHaveKey('from_following');
|
|
expect($sections)->not->toHaveKey('by_tags');
|
|
expect($sections)->not->toHaveKey('by_categories');
|
|
});
|
|
|
|
it('authenticated homepage contains all personalised sections', function () {
|
|
$user = User::factory()->create();
|
|
$sections = app(HomepageService::class)->allForUser($user);
|
|
|
|
expect($sections)->toHaveKeys([
|
|
'hero',
|
|
'from_following',
|
|
'trending',
|
|
'by_tags',
|
|
'by_categories',
|
|
'tags',
|
|
'creators',
|
|
'news',
|
|
'preferences',
|
|
]);
|
|
});
|
|
|
|
it('preferences section exposes top_tags and top_categories arrays', function () {
|
|
$user = User::factory()->create();
|
|
$sections = app(HomepageService::class)->allForUser($user);
|
|
|
|
expect($sections['preferences'])->toHaveKeys(['top_tags', 'top_categories']);
|
|
expect($sections['preferences']['top_tags'])->toBeArray();
|
|
expect($sections['preferences']['top_categories'])->toBeArray();
|
|
});
|
|
|
|
it('guest and auth homepages have different key sets', function () {
|
|
$user = User::factory()->create();
|
|
|
|
$guest = array_keys(app(HomepageService::class)->all());
|
|
$auth = array_keys(app(HomepageService::class)->allForUser($user));
|
|
|
|
expect($guest)->not->toEqual($auth);
|
|
expect(in_array('from_following', $auth))->toBeTrue();
|
|
expect(in_array('from_following', $guest))->toBeFalse();
|
|
});
|
|
|
|
it('homepage artwork payload uses group name and avatar for group-published artworks', function () {
|
|
$owner = User::factory()->create();
|
|
$group = Group::factory()->create([
|
|
'owner_user_id' => $owner->id,
|
|
'name' => 'Skinbase Collective',
|
|
'slug' => 'skinbase-collective',
|
|
]);
|
|
|
|
Artwork::factory()->create([
|
|
'user_id' => $owner->id,
|
|
'group_id' => $group->id,
|
|
'published_as_type' => Artwork::PUBLISHED_AS_GROUP,
|
|
'title' => 'Group Published Artwork',
|
|
'hash' => 'homepagegroupartwork',
|
|
'thumb_ext' => 'webp',
|
|
'published_at' => now()->subMinute(),
|
|
]);
|
|
|
|
Cache::flush();
|
|
|
|
$items = app(HomepageService::class)->getFreshUploads(10);
|
|
|
|
expect($items)->not->toBeEmpty()
|
|
->and($items[0]['author'])->toBe('Skinbase Collective')
|
|
->and($items[0]['author_username'])->toBe('')
|
|
->and($items[0]['published_as_type'])->toBe(Artwork::PUBLISHED_AS_GROUP)
|
|
->and($items[0]['publisher']['type'])->toBe('group')
|
|
->and($items[0]['publisher']['name'])->toBe('Skinbase Collective')
|
|
->and($items[0]['publisher']['profile_url'])->toContain('/groups/skinbase-collective');
|
|
});
|