new test files
This commit is contained in:
226
tests/Feature/Profile/WorldProfileHistoryTest.php
Normal file
226
tests/Feature/Profile/WorldProfileHistoryTest.php
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Models\Artwork;
|
||||
use App\Models\Group;
|
||||
use App\Models\GroupChallenge;
|
||||
use App\Models\GroupChallengeOutcome;
|
||||
use App\Models\User;
|
||||
use App\Models\World;
|
||||
use App\Models\WorldRewardGrant;
|
||||
use App\Models\WorldSubmission;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Inertia\Testing\AssertableInertia;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
function createPublicWorldForProfileHistory(array $overrides = []): World
|
||||
{
|
||||
return World::factory()->create(array_merge([
|
||||
'title' => 'World History ' . strtolower(fake()->bothify('####')),
|
||||
'slug' => 'world-history-' . strtolower(fake()->bothify('####')),
|
||||
'status' => World::STATUS_PUBLISHED,
|
||||
'published_at' => now()->subDay(),
|
||||
], $overrides));
|
||||
}
|
||||
|
||||
function createPublicArtworkForProfileHistory(User $creator, array $overrides = []): Artwork
|
||||
{
|
||||
return Artwork::factory()->for($creator)->create(array_merge([
|
||||
'title' => 'World Artwork ' . strtolower(fake()->bothify('####')),
|
||||
'slug' => 'world-artwork-' . strtolower(fake()->bothify('####')),
|
||||
'artwork_status' => 'published',
|
||||
'published_at' => now()->subDay(),
|
||||
'is_public' => true,
|
||||
'visibility' => Artwork::VISIBILITY_PUBLIC,
|
||||
'is_approved' => true,
|
||||
], $overrides));
|
||||
}
|
||||
|
||||
it('exposes normalized world history on public profile pages', function (): void {
|
||||
$creator = User::factory()->create([
|
||||
'username' => 'worldhist-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
$groupOwner = User::factory()->create();
|
||||
$group = Group::factory()->create([
|
||||
'owner_user_id' => $groupOwner->id,
|
||||
'visibility' => Group::VISIBILITY_PUBLIC,
|
||||
'status' => Group::LIFECYCLE_ACTIVE,
|
||||
]);
|
||||
|
||||
$challenge = GroupChallenge::query()->create([
|
||||
'group_id' => $group->id,
|
||||
'title' => 'Autumn Finals',
|
||||
'slug' => 'autumn-finals-' . strtolower(fake()->bothify('####')),
|
||||
'summary' => 'Final round challenge.',
|
||||
'description' => 'Final round challenge.',
|
||||
'visibility' => GroupChallenge::VISIBILITY_PUBLIC,
|
||||
'participation_scope' => GroupChallenge::PARTICIPATION_PUBLIC,
|
||||
'status' => GroupChallenge::STATUS_ACTIVE,
|
||||
'start_at' => now()->subDays(2),
|
||||
'end_at' => now()->addDays(2),
|
||||
'created_by_user_id' => $groupOwner->id,
|
||||
]);
|
||||
|
||||
$world = createPublicWorldForProfileHistory([
|
||||
'title' => 'Autumn Finals 2026',
|
||||
'slug' => 'autumn-finals-2026-' . strtolower(fake()->bothify('####')),
|
||||
'linked_challenge_id' => $challenge->id,
|
||||
'recurrence_key' => 'autumn-finals',
|
||||
'edition_year' => 2026,
|
||||
]);
|
||||
|
||||
$artwork = createPublicArtworkForProfileHistory($creator, [
|
||||
'title' => 'Autumn Skyline',
|
||||
'slug' => 'autumn-skyline-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
WorldSubmission::query()->create([
|
||||
'world_id' => $world->id,
|
||||
'artwork_id' => $artwork->id,
|
||||
'submitted_by_user_id' => $creator->id,
|
||||
'status' => WorldSubmission::STATUS_LIVE,
|
||||
'is_featured' => false,
|
||||
'reviewed_at' => now()->subDay(),
|
||||
]);
|
||||
|
||||
GroupChallengeOutcome::query()->create([
|
||||
'group_challenge_id' => $challenge->id,
|
||||
'artwork_id' => $artwork->id,
|
||||
'user_id' => $creator->id,
|
||||
'outcome_type' => GroupChallengeOutcome::TYPE_WINNER,
|
||||
'awarded_by_user_id' => $groupOwner->id,
|
||||
'awarded_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
$this->get(route('profile.show', ['username' => strtolower((string) $creator->username)]))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Profile/ProfileShow')
|
||||
->where('worldHistory.summary.available', true)
|
||||
->where('worldHistory.summary.world_appearances', 1)
|
||||
->where('worldHistory.summary.worlds_joined', 1)
|
||||
->where('worldHistory.summary.winner_appearances', 1)
|
||||
->where('worldHistory.summary.most_recent_world_activity.primary_recognition.key', 'winner')
|
||||
->where('worldHistory.entries.0.world.title', 'Autumn Finals 2026')
|
||||
->where('worldHistory.entries.0.primary_recognition.key', 'winner')
|
||||
->where('worldHistory.entries.0.recognition_keys.0', 'winner')
|
||||
->where('worldHistory.entries.0.challenge.title', 'Autumn Finals')
|
||||
->where('worldHistory.entries.0.linked_artwork.title', 'Autumn Skyline'));
|
||||
});
|
||||
|
||||
it('filters stale public world rewards while preserving owner-only context counts', function (): void {
|
||||
$creator = User::factory()->create([
|
||||
'username' => 'worldfilter-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
$staleWorld = createPublicWorldForProfileHistory([
|
||||
'title' => 'Removed Entry World',
|
||||
'slug' => 'removed-entry-world-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
$pendingWorld = createPublicWorldForProfileHistory([
|
||||
'title' => 'Pending Entry World',
|
||||
'slug' => 'pending-entry-world-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
$removedArtwork = createPublicArtworkForProfileHistory($creator, [
|
||||
'title' => 'Removed Entry Artwork',
|
||||
'slug' => 'removed-entry-artwork-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
$pendingArtwork = createPublicArtworkForProfileHistory($creator, [
|
||||
'title' => 'Pending Entry Artwork',
|
||||
'slug' => 'pending-entry-artwork-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
$removedSubmission = WorldSubmission::query()->create([
|
||||
'world_id' => $staleWorld->id,
|
||||
'artwork_id' => $removedArtwork->id,
|
||||
'submitted_by_user_id' => $creator->id,
|
||||
'status' => WorldSubmission::STATUS_REMOVED,
|
||||
'removed_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
WorldRewardGrant::query()->create([
|
||||
'user_id' => $creator->id,
|
||||
'world_id' => $staleWorld->id,
|
||||
'artwork_id' => $removedArtwork->id,
|
||||
'world_submission_id' => $removedSubmission->id,
|
||||
'reward_type' => 'participant',
|
||||
'grant_source' => 'automatic',
|
||||
'granted_at' => now()->subMinutes(30),
|
||||
]);
|
||||
|
||||
WorldSubmission::query()->create([
|
||||
'world_id' => $pendingWorld->id,
|
||||
'artwork_id' => $pendingArtwork->id,
|
||||
'submitted_by_user_id' => $creator->id,
|
||||
'status' => WorldSubmission::STATUS_PENDING,
|
||||
]);
|
||||
|
||||
$this->get(route('profile.show', ['username' => strtolower((string) $creator->username)]))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Profile/ProfileShow')
|
||||
->where('worldHistory.summary.available', false)
|
||||
->where('worldHistory.entries', [])
|
||||
->where('worldHistory.owner_context', null));
|
||||
|
||||
$this->actingAs($creator)
|
||||
->get(route('profile.show', ['username' => strtolower((string) $creator->username)]))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Profile/ProfileShow')
|
||||
->where('worldHistory.summary.available', false)
|
||||
->where('worldHistory.owner_context.pending_submissions', 1)
|
||||
->where('worldHistory.owner_context.removed_or_blocked_submissions', 1)
|
||||
->where('worldHistory.owner_context.hidden_public_entries', 1));
|
||||
});
|
||||
|
||||
it('supports the canonical worlds profile tab route', function (): void {
|
||||
$creator = User::factory()->create([
|
||||
'username' => 'worldtab-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
$world = createPublicWorldForProfileHistory([
|
||||
'title' => 'Featured Worlds 2026',
|
||||
'slug' => 'featured-worlds-2026-' . strtolower(fake()->bothify('####')),
|
||||
'edition_year' => 2026,
|
||||
]);
|
||||
|
||||
$artwork = createPublicArtworkForProfileHistory($creator, [
|
||||
'title' => 'Featured Worlds Artwork',
|
||||
'slug' => 'featured-worlds-artwork-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
|
||||
$submission = WorldSubmission::query()->create([
|
||||
'world_id' => $world->id,
|
||||
'artwork_id' => $artwork->id,
|
||||
'submitted_by_user_id' => $creator->id,
|
||||
'status' => WorldSubmission::STATUS_LIVE,
|
||||
'is_featured' => true,
|
||||
'featured_at' => now()->subMinutes(10),
|
||||
]);
|
||||
|
||||
WorldRewardGrant::query()->create([
|
||||
'user_id' => $creator->id,
|
||||
'world_id' => $world->id,
|
||||
'artwork_id' => $artwork->id,
|
||||
'world_submission_id' => $submission->id,
|
||||
'reward_type' => 'featured',
|
||||
'grant_source' => 'automatic',
|
||||
'granted_at' => now()->subMinutes(5),
|
||||
]);
|
||||
|
||||
$this->get(route('profile.tab', ['username' => strtolower((string) $creator->username), 'tab' => 'worlds']))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Profile/ProfileShow')
|
||||
->where('initialTab', 'worlds')
|
||||
->where('profileTabUrls.worlds', url('/@' . strtolower((string) $creator->username) . '/worlds'))
|
||||
->where('worldHistory.summary.available', true)
|
||||
->where('worldHistory.entries.0.primary_recognition.key', 'featured'));
|
||||
});
|
||||
118
tests/Feature/Profile/WorldRewardsProfileTest.php
Normal file
118
tests/Feature/Profile/WorldRewardsProfileTest.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Models\Artwork;
|
||||
use App\Models\User;
|
||||
use App\Models\World;
|
||||
use App\Models\WorldRewardGrant;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Inertia\Testing\AssertableInertia;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
it('exposes world rewards on public profile pages', function (): void {
|
||||
$creator = User::factory()->create([
|
||||
'username' => 'profilerewards-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
$worldOwner = User::factory()->create();
|
||||
$world = World::factory()->create([
|
||||
'title' => 'Spring Vibes 2026',
|
||||
'slug' => 'spring-vibes-2026-' . strtolower(fake()->bothify('####')),
|
||||
'status' => World::STATUS_PUBLISHED,
|
||||
'published_at' => now()->subDay(),
|
||||
'created_by_user_id' => $worldOwner->id,
|
||||
]);
|
||||
$artwork = Artwork::factory()->for($creator)->create([
|
||||
'title' => 'Profile Reward Artwork',
|
||||
'slug' => 'profile-reward-artwork',
|
||||
'artwork_status' => 'published',
|
||||
'published_at' => now()->subDay(),
|
||||
'is_public' => true,
|
||||
'visibility' => Artwork::VISIBILITY_PUBLIC,
|
||||
]);
|
||||
|
||||
WorldRewardGrant::query()->create([
|
||||
'user_id' => $creator->id,
|
||||
'world_id' => $world->id,
|
||||
'artwork_id' => $artwork->id,
|
||||
'reward_type' => 'featured',
|
||||
'grant_source' => 'automatic',
|
||||
'granted_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
$this->get(route('profile.show', ['username' => strtolower((string) $creator->username)]))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Profile/ProfileShow')
|
||||
->where('worldRewards.count', 1)
|
||||
->where('worldRewards.items.0.badge_label', 'Spring Vibes 2026 Featured'));
|
||||
});
|
||||
|
||||
it('prioritizes higher-signal world rewards ahead of participation on profile reward grids while keeping recents chronological', function (): void {
|
||||
$creator = User::factory()->create([
|
||||
'username' => 'profilepriority-' . strtolower(fake()->bothify('####')),
|
||||
]);
|
||||
$worldOwner = User::factory()->create();
|
||||
|
||||
$participantWorld = World::factory()->create([
|
||||
'title' => 'Retro Month 2026',
|
||||
'slug' => 'retro-month-2026-' . strtolower(fake()->bothify('####')),
|
||||
'status' => World::STATUS_PUBLISHED,
|
||||
'published_at' => now()->subDay(),
|
||||
'created_by_user_id' => $worldOwner->id,
|
||||
]);
|
||||
|
||||
$winnerWorld = World::factory()->create([
|
||||
'title' => 'Pixel Week 2026',
|
||||
'slug' => 'pixel-week-2026-' . strtolower(fake()->bothify('####')),
|
||||
'status' => World::STATUS_PUBLISHED,
|
||||
'published_at' => now()->subDay(),
|
||||
'created_by_user_id' => $worldOwner->id,
|
||||
]);
|
||||
|
||||
$participantArtwork = Artwork::factory()->for($creator)->create([
|
||||
'title' => 'Participant Artwork',
|
||||
'slug' => 'participant-artwork',
|
||||
'artwork_status' => 'published',
|
||||
'published_at' => now()->subDay(),
|
||||
'is_public' => true,
|
||||
'visibility' => Artwork::VISIBILITY_PUBLIC,
|
||||
]);
|
||||
|
||||
$winnerArtwork = Artwork::factory()->for($creator)->create([
|
||||
'title' => 'Winner Artwork',
|
||||
'slug' => 'winner-artwork',
|
||||
'artwork_status' => 'published',
|
||||
'published_at' => now()->subDay(),
|
||||
'is_public' => true,
|
||||
'visibility' => Artwork::VISIBILITY_PUBLIC,
|
||||
]);
|
||||
|
||||
WorldRewardGrant::query()->create([
|
||||
'user_id' => $creator->id,
|
||||
'world_id' => $participantWorld->id,
|
||||
'artwork_id' => $participantArtwork->id,
|
||||
'reward_type' => 'participant',
|
||||
'grant_source' => 'automatic',
|
||||
'granted_at' => now()->subMinutes(10),
|
||||
]);
|
||||
|
||||
WorldRewardGrant::query()->create([
|
||||
'user_id' => $creator->id,
|
||||
'world_id' => $winnerWorld->id,
|
||||
'artwork_id' => $winnerArtwork->id,
|
||||
'reward_type' => 'winner',
|
||||
'grant_source' => 'manual',
|
||||
'granted_at' => now()->subHour(),
|
||||
]);
|
||||
|
||||
$this->get(route('profile.show', ['username' => strtolower((string) $creator->username)]))
|
||||
->assertOk()
|
||||
->assertInertia(fn (AssertableInertia $page) => $page
|
||||
->component('Profile/ProfileShow')
|
||||
->where('worldRewards.count', 2)
|
||||
->where('worldRewards.items.0.badge_label', 'Pixel Week 2026 Winner')
|
||||
->where('worldRewards.items.1.badge_label', 'Retro Month 2026 Participant')
|
||||
->where('worldRewards.recent.0.badge_label', 'Retro Month 2026 Participant'));
|
||||
});
|
||||
Reference in New Issue
Block a user