feat: totalXp
This commit is contained in:
parent
2894b59452
commit
33f87bfa10
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Enums\HuntDifficulty;
|
use App\Enums\HuntDifficulty;
|
||||||
|
use App\Http\Resources\HuntResource;
|
||||||
use App\Models\Hunts;
|
use App\Models\Hunts;
|
||||||
use App\Notifications\HuntParticipantJoinedNotification;
|
use App\Notifications\HuntParticipantJoinedNotification;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
@ -22,14 +23,6 @@ class HuntsController extends Controller
|
||||||
->query(fn ($query) => $query->with('participants:id,avatar_uri'))
|
->query(fn ($query) => $query->with('participants:id,avatar_uri'))
|
||||||
->options(['filter' => $filters]);
|
->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);
|
$result = $search->paginate(10);
|
||||||
|
|
||||||
Log::info('HUNTS_SEARCH_SUCCESS', [
|
Log::info('HUNTS_SEARCH_SUCCESS', [
|
||||||
|
|
@ -39,12 +32,6 @@ class HuntsController extends Controller
|
||||||
|
|
||||||
return response()->json($result);
|
return response()->json($result);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
Log::error('HUNTS_ERROR_CAUGHT', [
|
|
||||||
'message' => $e->getMessage(),
|
|
||||||
'file' => $e->getFile(),
|
|
||||||
'line' => $e->getLine(),
|
|
||||||
'trace' => $e->getTraceAsString(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'Server Error',
|
'error' => 'Server Error',
|
||||||
|
|
@ -68,7 +55,7 @@ class HuntsController extends Controller
|
||||||
'hunt_title' => $hunt->title,
|
'hunt_title' => $hunt->title,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json($hunt);
|
return HuntResource::make($hunt)->response();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
Log::error('HUNT_SHOW_ERROR', [
|
Log::error('HUNT_SHOW_ERROR', [
|
||||||
'hunt_id' => $hunt->id ?? null,
|
'hunt_id' => $hunt->id ?? null,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class HuntResource extends JsonResource
|
||||||
|
{
|
||||||
|
public static $wrap = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Hunts;
|
||||||
|
use App\Models\HuntSteps;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Testing\Fluent\AssertableJson;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('shows a hunt with participants, steps, and total step xp', function () {
|
||||||
|
$user = User::factory()->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()
|
||||||
|
);
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue