Skip to content

Commit

Permalink
fix(API_GetUserGameLeaderboards): don't crash on deleted leaderboards (
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored Feb 6, 2025
1 parent 836cf18 commit 3ef72d3
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
10 changes: 6 additions & 4 deletions public/API/API_GetUserGameLeaderboards.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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'),
Expand All @@ -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)
Expand Down
65 changes: 65 additions & 0 deletions tests/Feature/Api/V1/GetUserGameLeaderboardsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
],
],
],
]);
}
}

0 comments on commit 3ef72d3

Please sign in to comment.