From 3ef72d389fa5e5e2014d6e6d9cc22478939e4164 Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Thu, 6 Feb 2025 06:59:43 -0500 Subject: [PATCH] fix(API_GetUserGameLeaderboards): don't crash on deleted leaderboards (#3180) --- public/API/API_GetUserGameLeaderboards.php | 10 +-- .../Api/V1/GetUserGameLeaderboardsTest.php | 65 +++++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/public/API/API_GetUserGameLeaderboards.php b/public/API/API_GetUserGameLeaderboards.php index 1a0adb2414..2d546a0389 100644 --- a/public/API/API_GetUserGameLeaderboards.php +++ b/public/API/API_GetUserGameLeaderboards.php @@ -61,8 +61,9 @@ ->join('UserAccounts', 'leaderboard_entries.user_id', '=', 'UserAccounts.ID') ->whereIn('leaderboard_id', function ($query) use ($game) { $query->select('ID') - ->from('LeaderboardDef') - ->where('GameID', $game->ID); + ->from('LeaderboardDef') + ->where('GameID', $game->ID) + ->whereNull('deleted_at'); }) ->whereNull('UserAccounts.unranked_at') ->where('UserAccounts.Untracked', 0) @@ -85,10 +86,10 @@ ->where(function ($query) { $query->where(function ($q) { $q->where('leaderboard_rank_calc.LowerIsBetter', 1) - ->whereColumn('entries_rank_calc.score', '<', 'leaderboard_entries.score'); + ->whereColumn('entries_rank_calc.score', '<', 'leaderboard_entries.score'); })->orWhere(function ($q) { $q->where('leaderboard_rank_calc.LowerIsBetter', 0) - ->whereColumn('entries_rank_calc.score', '>', 'leaderboard_entries.score'); + ->whereColumn('entries_rank_calc.score', '>', 'leaderboard_entries.score'); }); }) ->selectRaw('COUNT(*) + 1'), @@ -99,6 +100,7 @@ ->where('leaderboard_entries.user_id', $user->id) ->whereNull('UserAccounts.unranked_at') ->where('UserAccounts.Untracked', 0) + ->whereNull('LeaderboardDef.deleted_at') ->with('leaderboard') ->orderBy('LeaderboardDef.ID', 'asc') ->skip($offset) diff --git a/tests/Feature/Api/V1/GetUserGameLeaderboardsTest.php b/tests/Feature/Api/V1/GetUserGameLeaderboardsTest.php index 31cc769cbc..88719e4a4f 100644 --- a/tests/Feature/Api/V1/GetUserGameLeaderboardsTest.php +++ b/tests/Feature/Api/V1/GetUserGameLeaderboardsTest.php @@ -811,4 +811,69 @@ public function testGetUserGameLeaderboardsRankCalculationWhenTie(): void ], ]); } + + public function testGetUserGameLeaderboardsDoesNotIncludeDeletedLeaderboards(): void + { + Carbon::setTestNow(Carbon::now()); + + /** @var System $system */ + $system = System::factory()->create(); + + /** @var Game $game */ + $game = Game::factory()->create(['ConsoleID' => $system->ID]); + + /** @var Leaderboard $activeLeaderboard */ + $activeLeaderboard = Leaderboard::factory()->create([ + 'GameID' => $game->ID, + 'Title' => "Active leaderboard", + 'Description' => "I am active", + 'LowerIsBetter' => true, + ]); + + /** @var Leaderboard $deletedLeaderboard */ + $deletedLeaderboard = Leaderboard::factory()->create([ + 'GameID' => $game->ID, + 'Title' => "Deleted leaderboard", + 'Description' => "I am deleted", + 'LowerIsBetter' => true, + 'deleted_at' => now(), + ]); + + $user = User::factory()->create(['User' => 'testUser']); + + // ... create entries for both leaderboards ... + $activeEntry = LeaderboardEntry::factory()->create([ + 'leaderboard_id' => $activeLeaderboard->ID, + 'user_id' => $user->ID, + 'score' => 100, + ]); + LeaderboardEntry::factory()->create([ + 'leaderboard_id' => $deletedLeaderboard->ID, + 'user_id' => $user->ID, + 'score' => 200, + ]); + + $this->get($this->apiUrl('GetUserGameLeaderboards', ['i' => $game->ID, 'u' => $user->User])) + ->assertSuccessful() + ->assertJson([ + 'Count' => 1, + 'Total' => 1, // !! only count the non-deleted leaderboard + 'Results' => [ + [ + 'ID' => $activeLeaderboard->ID, + 'RankAsc' => $activeLeaderboard->LowerIsBetter, + 'Title' => $activeLeaderboard->Title, + 'Description' => $activeLeaderboard->Description, + 'Format' => $activeLeaderboard->Format, + 'UserEntry' => [ // !! just one entry, for the non-deleted leaderboard + 'User' => $user->User, + 'Score' => $activeEntry->score, + 'FormattedScore' => ValueFormat::format($activeEntry->score, $activeLeaderboard->Format), + 'Rank' => 1, + 'DateUpdated' => $activeEntry->created_at->toIso8601String(), + ], + ], + ], + ]); + } }