266 lines
5.6 KiB
Markdown
266 lines
5.6 KiB
Markdown
# Foundry Factories for MineSeeker
|
||
|
||
Factory classes for creating test data. For general Foundry usage, see [Zenstruck Foundry Docs](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html).
|
||
|
||
---
|
||
|
||
## Available Factories
|
||
|
||
All factories are in `tests/Factory/`:
|
||
|
||
| Factory | Entity | Use For |
|
||
|---------|--------|---------|
|
||
| `UserFactory` | `User` | Registered users with auth |
|
||
| `GamerFactory` | `Gamer` | Anonymous/guest players |
|
||
| `PlayedGameFactory` | `PlayedGame` | Game records |
|
||
| `StepFactory` | `Step` | Individual game moves |
|
||
| `GridFactory` | `Grid` | 16×16 game grids |
|
||
| `GridRowFactory` | `GridRow` | Grid row data |
|
||
| `WebAuthnCredentialFactory` | `WebAuthnCredential` | Passkey credentials |
|
||
| `ContactMessageFactory` | `ContactMessage` | Contact form messages |
|
||
|
||
---
|
||
|
||
## Quick Examples
|
||
|
||
### UserFactory
|
||
|
||
```php
|
||
// Basic user
|
||
$user = UserFactory::createOne();
|
||
|
||
// Unverified user
|
||
$user = UserFactory::createOne(['isVerified' => false]);
|
||
|
||
// Admin user
|
||
$user = UserFactory::createOne(['roles' => ['ROLE_ADMIN']]);
|
||
|
||
// Multiple users
|
||
UserFactory::createMany(5);
|
||
```
|
||
|
||
### GamerFactory
|
||
|
||
```php
|
||
// Anonymous gamer
|
||
$gamer = GamerFactory::new()->anonymous()->create();
|
||
```
|
||
|
||
### PlayedGameFactory
|
||
|
||
```php
|
||
// Game with registered players
|
||
$game = PlayedGameFactory::new()
|
||
->withRegisteredPlayers()
|
||
->create();
|
||
|
||
// Game with anonymous players
|
||
$game = PlayedGameFactory::new()
|
||
->withAnonymousPlayers()
|
||
->create();
|
||
|
||
// Red wins
|
||
$game = PlayedGameFactory::new()
|
||
->withRegisteredPlayers()
|
||
->redWins()
|
||
->create();
|
||
|
||
// Blue wins
|
||
$game = PlayedGameFactory::new()
|
||
->withRegisteredPlayers()
|
||
->blueWins()
|
||
->create();
|
||
|
||
// Resigned game
|
||
$game = PlayedGameFactory::new()
|
||
->resigned('red')
|
||
->create();
|
||
```
|
||
|
||
### StepFactory
|
||
|
||
```php
|
||
// Mine hit
|
||
$step = StepFactory::new()
|
||
->forPlayer('red')
|
||
->mine()
|
||
->create(['playedGame' => $game]);
|
||
|
||
// Safe cell
|
||
$step = StepFactory::new()
|
||
->forPlayer('blue')
|
||
->safe()
|
||
->create(['playedGame' => $game]);
|
||
|
||
// With revealed cells
|
||
$step = StepFactory::new()
|
||
->withRevealedCells([
|
||
['row' => 5, 'col' => 5],
|
||
['row' => 5, 'col' => 6],
|
||
])
|
||
->create(['playedGame' => $game]);
|
||
```
|
||
|
||
### GridFactory
|
||
|
||
```php
|
||
// Full 16×16 grid
|
||
$grid = GridFactory::createOne(['playedGame' => $game]);
|
||
|
||
// Automatically creates 16 rows
|
||
self::assertCount(16, $grid->gridRow);
|
||
```
|
||
|
||
### WebAuthnCredentialFactory
|
||
|
||
```php
|
||
// Basic credential
|
||
$credential = WebAuthnCredentialFactory::createOne(['user' => $user]);
|
||
|
||
// Named credential, recently used
|
||
$credential = WebAuthnCredentialFactory::new()
|
||
->withName('YubiKey 5C')
|
||
->recentlyUsed()
|
||
->create(['user' => $user]);
|
||
```
|
||
|
||
### ContactMessageFactory
|
||
|
||
```php
|
||
// Basic message
|
||
$message = ContactMessageFactory::createOne();
|
||
|
||
// Without consent
|
||
$message = ContactMessageFactory::new()
|
||
->withoutConsent()
|
||
->create();
|
||
```
|
||
|
||
---
|
||
|
||
## Factory API Reference
|
||
|
||
### Common Methods (All Factories)
|
||
|
||
```php
|
||
// Create single entity
|
||
Factory::createOne([
|
||
'property' => 'value',
|
||
]);
|
||
|
||
// Create multiple
|
||
Factory::createMany(5);
|
||
|
||
// Create with factory methods
|
||
Factory::new()
|
||
->customMethod()
|
||
->create(['property' => 'value']);
|
||
|
||
// Access repository
|
||
Factory::repository()->findAll();
|
||
Factory::repository()->count([]);
|
||
Factory::repository()->findBy(['field' => 'value']);
|
||
```
|
||
|
||
### PlayedGameFactory Methods
|
||
|
||
| Method | Description |
|
||
|--------|-------------|
|
||
| `withRegisteredPlayers()` | Creates game with 2 registered users |
|
||
| `withAnonymousPlayers()` | Creates game with 2 anonymous gamers |
|
||
| `withMixedPlayers()` | One registered, one anonymous |
|
||
| `redWins()` | Red has 26 points |
|
||
| `blueWins()` | Blue has 26 points |
|
||
| `resigned(string $player)` | Set resignation ('red' or 'blue') |
|
||
|
||
### StepFactory Methods
|
||
|
||
| Method | Description |
|
||
|--------|-------------|
|
||
| `forPlayer(string $player)` | Set player ('red' or 'blue') |
|
||
| `mine()` | Step hits a mine |
|
||
| `safe()` | Step reveals safe cell |
|
||
| `withRevealedCells(array $cells)` | Set revealed cells array |
|
||
|
||
### GamerFactory Methods
|
||
|
||
| Method | Description |
|
||
|--------|-------------|
|
||
| `anonymous()` | Set username as "Guest_12345" |
|
||
|
||
### WebAuthnCredentialFactory Methods
|
||
|
||
| Method | Description |
|
||
|--------|-------------|
|
||
| `withName(string $name)` | Set credential name |
|
||
| `recentlyUsed()` | Set lastUsedAt to now |
|
||
|
||
### ContactMessageFactory Methods
|
||
|
||
| Method | Description |
|
||
|--------|-------------|
|
||
| `withoutConsent()` | Set consent to false |
|
||
| `anonymous()` | Remove IP address |
|
||
|
||
---
|
||
|
||
## MineSeeker-Specific Patterns
|
||
|
||
### Complete Game Setup
|
||
|
||
```php
|
||
// Create full game with steps and grid
|
||
$game = PlayedGameFactory::new()
|
||
->withRegisteredPlayers()
|
||
->create();
|
||
|
||
// Add steps
|
||
StepFactory::createMany(10, [
|
||
'playedGame' => $game,
|
||
'player' => 'red',
|
||
]);
|
||
|
||
// Add grid
|
||
$grid = GridFactory::createOne(['playedGame' => $game]);
|
||
```
|
||
|
||
### Testing Battle History
|
||
|
||
```php
|
||
// Create multiple finished games for a user
|
||
$user = UserFactory::createOne();
|
||
|
||
PlayedGameFactory::new()
|
||
->redWins()
|
||
->create(['red' => $user]);
|
||
|
||
PlayedGameFactory::new()
|
||
->blueWins()
|
||
->create(['blue' => $user]);
|
||
```
|
||
|
||
---
|
||
|
||
## Database Isolation
|
||
|
||
Tests automatically run in isolated transactions:
|
||
|
||
```php
|
||
public function testDatabaseIsolation(): void
|
||
{
|
||
UserFactory::createMany(5);
|
||
self::assertCount(5, UserFactory::repository()->findAll());
|
||
|
||
// Automatically rolled back after test
|
||
}
|
||
```
|
||
|
||
No manual cleanup needed. Each test starts with a clean database.
|
||
|
||
---
|
||
|
||
## External Resources
|
||
|
||
- **[Zenstruck Foundry Documentation](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html)** - Complete Foundry guide
|
||
- **[DAMA Doctrine Test Bundle](https://github.com/dmaicher/doctrine-test-bundle)** - Transaction isolation details
|