'null']); }); it('allForUser includes a for_you key', function () { $user = User::factory()->create(); Cache::flush(); $service = app(HomepageService::class); $result = $service->allForUser($user); expect($result)->toHaveKey('for_you') ->and($result['for_you'])->toBeArray(); }); it('allForUser for_you is an array even with no cached recommendations', function () { $user = User::factory()->create(); $service = app(HomepageService::class); Cache::flush(); $result = $service->allForUser($user); expect($result['for_you'])->toBeArray(); }); it('allForUser for_you returns items when cache exists', function () { $user = User::factory()->create(); $artwork = Artwork::factory()->create([ 'is_public' => true, 'is_approved' => true, 'published_at' => now()->subHour(), ]); UserRecommendationCache::query()->create([ 'user_id' => $user->id, 'algo_version' => (string) config('discovery.algo_version', 'clip-cosine-v1'), 'cache_version' => (string) config('discovery.cache_version', 'cache-v1'), 'recommendations_json' => [ 'items' => [ ['artwork_id' => $artwork->id, 'score' => 0.9, 'source' => 'profile'], ], ], 'generated_at' => now(), 'expires_at' => now()->addMinutes(60), ]); Cache::flush(); $service = app(HomepageService::class); $result = $service->allForUser($user); expect($result['for_you'])->toBeArray(); // At least one item should have the base shape (id, title, slug, url) if (count($result['for_you']) > 0) { expect($result['for_you'][0])->toHaveKeys(['id', 'title', 'slug', 'url']); } });