From 33f87bfa1053b43f4f0360af3a21d771c215dbf1 Mon Sep 17 00:00:00 2001 From: Leon Morival Date: Wed, 29 Apr 2026 14:52:00 +0200 Subject: [PATCH] feat: totalXp --- app/Http/Controllers/HuntsController.php | 17 +------ app/Http/Resources/HuntResource.php | 38 ++++++++++++++++ tests/Feature/HuntShowTest.php | 56 ++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 15 deletions(-) create mode 100644 app/Http/Resources/HuntResource.php create mode 100644 tests/Feature/HuntShowTest.php diff --git a/app/Http/Controllers/HuntsController.php b/app/Http/Controllers/HuntsController.php index ad015e0..af41ad4 100644 --- a/app/Http/Controllers/HuntsController.php +++ b/app/Http/Controllers/HuntsController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Enums\HuntDifficulty; +use App\Http\Resources\HuntResource; use App\Models\Hunts; use App\Notifications\HuntParticipantJoinedNotification; use Illuminate\Http\JsonResponse; @@ -22,14 +23,6 @@ class HuntsController extends Controller ->query(fn ($query) => $query->with('participants:id,avatar_uri')) ->options(['filter' => $filters]); - Log::info('HUNTS_SEARCH', [ - 'q' => $searchTerm ?? '', - 'filters' => $filters, - 'meili_host' => config('scout.meilisearch.host'), - 'index' => (new Hunts)->searchableAs(), - 'request_params' => $request->all(), - ]); - $result = $search->paginate(10); Log::info('HUNTS_SEARCH_SUCCESS', [ @@ -39,12 +32,6 @@ class HuntsController extends Controller return response()->json($result); } catch (\Throwable $e) { - Log::error('HUNTS_ERROR_CAUGHT', [ - 'message' => $e->getMessage(), - 'file' => $e->getFile(), - 'line' => $e->getLine(), - 'trace' => $e->getTraceAsString(), - ]); return response()->json([ 'error' => 'Server Error', @@ -68,7 +55,7 @@ class HuntsController extends Controller 'hunt_title' => $hunt->title, ]); - return response()->json($hunt); + return HuntResource::make($hunt)->response(); } catch (\Throwable $e) { Log::error('HUNT_SHOW_ERROR', [ 'hunt_id' => $hunt->id ?? null, diff --git a/app/Http/Resources/HuntResource.php b/app/Http/Resources/HuntResource.php new file mode 100644 index 0000000..8ca92f5 --- /dev/null +++ b/app/Http/Resources/HuntResource.php @@ -0,0 +1,38 @@ + + */ + public function toArray(Request $request): array + { + return array_merge(parent::toArray($request), [ + 'xp' => $this->totalXp(), + ]); + } + + private function totalXp(): int + { + if ($this->resource->relationLoaded('steps')) { + return (int) $this->resource->steps->sum('xp'); + } + + $stepsSumXp = $this->resource->getAttribute('steps_sum_xp'); + + if ($stepsSumXp !== null) { + return (int) $stepsSumXp; + } + + return (int) $this->resource->steps()->sum('xp'); + } +} diff --git a/tests/Feature/HuntShowTest.php b/tests/Feature/HuntShowTest.php new file mode 100644 index 0000000..8a7759d --- /dev/null +++ b/tests/Feature/HuntShowTest.php @@ -0,0 +1,56 @@ +create(); + $participant = User::factory()->create([ + 'avatar_uri' => 'avatars/participant.png', + 'xp' => 450, + ]); + $hunt = Hunts::withoutSyncingToSearch(fn () => Hunts::factory()->create([ + 'title' => 'Treasure hunt', + ])); + + $hunt->participants()->attach($participant->id, [ + 'current_step_number' => 1, + 'status' => 'in_progress', + ]); + + HuntSteps::factory()->create([ + 'hunt_id' => $hunt->id, + 'step_number' => 1, + 'title' => 'First step', + 'xp' => 125, + ]); + + HuntSteps::factory()->create([ + 'hunt_id' => $hunt->id, + 'step_number' => 2, + 'title' => 'Second step', + 'xp' => 75, + ]); + + $response = $this + ->actingAs($user, 'sanctum') + ->getJson("/api/hunts/{$hunt->id}"); + + $response + ->assertOk() + ->assertJson(fn (AssertableJson $json) => $json + ->where('id', $hunt->id) + ->where('title', 'Treasure hunt') + ->where('xp', 200) + ->has('participants', 1) + ->where('participants.0.id', $participant->id) + ->where('participants.0.username', $participant->username) + ->has('steps', 2) + ->etc() + ); +});