Skip to content

Commit

Permalink
test(GameSuggestionEngine): resolve flake from randomness (#3056)
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored Jan 13, 2025
1 parent a43a687 commit b8d8ad1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 23 deletions.
11 changes: 10 additions & 1 deletion app/Platform/Services/GameSuggestions/GameSuggestionEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use App\Models\UserGameListEntry;
use App\Platform\Data\GameSuggestionData;
use App\Platform\Services\GameSuggestions\Enums\SourceGameKind;
use App\Platform\Services\GameSuggestions\Strategies\GameSuggestionStrategy;
use Illuminate\Support\Collection;

class GameSuggestionEngine
Expand All @@ -26,6 +27,14 @@ public function __construct(
$this->initializeStrategies($user);
}

/**
* For testing purposes only.
*/
public function dangerouslySetFixedStrategyForTesting(GameSuggestionStrategy $strategy, int $weight = 1): void
{
$this->strategies = [[$strategy, $weight]];
}

private function initializeStrategies(User $user): void
{
// Strategies and games will be picked at random, but we can assign weights to our strategies.
Expand Down Expand Up @@ -198,7 +207,7 @@ private function fastPickRandomBacklogGameEntries(User $user): Collection

}

private function selectWeightedStrategy(): Strategies\GameSuggestionStrategy
private function selectWeightedStrategy(): GameSuggestionStrategy
{
$total = array_sum(array_column($this->strategies, 1));
$random = random_int(1, (int) $total);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
use App\Models\User;
use App\Platform\Enums\GameSetType;
use App\Platform\Services\GameSuggestions\GameSuggestionEngine;
use App\Platform\Services\GameSuggestions\Strategies\SimilarGameStrategy;
use App\Platform\Services\GameSuggestions\Strategies\WantToPlayStrategy;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

Expand All @@ -34,6 +36,9 @@ public function testItReturnsUserSpecificSuggestionsWithinLimit(): void

// Act
$engine = new GameSuggestionEngine($user);
$engine->dangerouslySetFixedStrategyForTesting(
new WantToPlayStrategy($user)
);
$suggestions = $engine->selectSuggestions(limit: 3);

// Assert
Expand Down Expand Up @@ -61,6 +66,9 @@ public function testItReturnsGameSpecificSuggestions(): void

// Act
$engine = new GameSuggestionEngine($user, $sourceGame);
$engine->dangerouslySetFixedStrategyForTesting(
new SimilarGameStrategy($sourceGame, attachContext: false)
);
$suggestions = $engine->selectSuggestions(limit: 2);

// Assert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,26 +75,22 @@ public function testItRandomlySelectsFromMultipleHubs(): void
// Arrange
$sourceGame = Game::factory()->create(['achievements_published' => 10]);

// ... create two different hubs ...
$sonicHub = GameSet::factory()->create([
'type' => GameSetType::Hub,
'title' => '[Series - Sonic the Hedgehog]',
]);
$platformerHub = GameSet::factory()->create([
'type' => GameSetType::Hub,
'title' => '[Genre - 2D Platformer]',
]);

$sonicGame = Game::factory()->create(['achievements_published' => 10]);
$platformerGame = Game::factory()->create(['achievements_published' => 10]);

$sonicHub->games()->attach([$sourceGame->id, $sonicGame->id]);
$platformerHub->games()->attach([$sourceGame->id, $platformerGame->id]);
$hubCount = 10;
$games = [];
$hubs = [];
for ($i = 0; $i < $hubCount; $i++) {
$hubs[$i] = GameSet::factory()->create([
'type' => GameSetType::Hub,
'title' => $i === 0 ? '[Series - Sonic the Hedgehog]' : "[Hub {$i}]",
]);

$games[$i] = Game::factory()->create(['achievements_published' => 10]);
$hubs[$i]->games()->attach([$sourceGame->id, $games[$i]->id]);
}

// Act - we'll sample multiple times to ensure we get games from both hubs
$seenGames = [];
$seenHubs = [];
for ($i = 0; $i < 10; $i++) {
for ($i = 0; $i < 20; $i++) {
$strategy = new SharedHubStrategy($sourceGame);
$result = $strategy->select();

Expand All @@ -108,11 +104,8 @@ public function testItRandomlySelectsFromMultipleHubs(): void
}

// Assert
$this->assertTrue(in_array($sonicGame->id, $seenGames));
$this->assertTrue(in_array($platformerGame->id, $seenGames));

$this->assertTrue(in_array($sonicHub->id, $seenHubs));
$this->assertTrue(in_array($platformerHub->id, $seenHubs));
$this->assertGreaterThan(5, count(array_unique($seenGames)));
$this->assertGreaterThan(5, count(array_unique($seenHubs)));
}

public function testItIgnoresHubsWithOnlyOneGame(): void
Expand Down

0 comments on commit b8d8ad1

Please sign in to comment.