# Testing Guide

Use PHPUnit 9. Start with the smallest relevant test.

## Test groups

- `tests/auto/models/` - Integration tests against real databases for different game type models
- `tests/auto/models-cms/` - CMS model tests
- `tests/auto/integration/` - HTTP integration tests

## Common commands

```bash
composer test
composer test-web
composer test-all
composer run test-model-cms
composer test-integration
```

Source-specific model suites are exposed through Composer scripts such as `composer test-emulator` and `composer test-stream`.

## Single test runs

Model test:

```bash
# Single test file
phpunit --testdox --bootstrap ./tests/auto/models/config/emulator.php tests/auto/models/accountModelTest.php --debug
# Single test method
phpunit --testdox --bootstrap ./tests/auto/models/config/emulator.php --filter testGetByUID tests/auto/models/entitiesModelTest.php --debug
```

## Bootstrap layout

Tests use bootstrap files instead of `phpunit.xml`. A bootstrap sets source-specific constants, loads Composer autoloading, and pulls in app helpers.

| Path | Purpose |
|---|---|
| `tests/auto/models/config/<SOURCE_MODEL>.php` | Custom models |
| `tests/auto/integration-web/config.php` | HTTP web tests |

## Model test pattern

- To validate Players and Guilds `require_once 'tests/auto/models/helpers.php'`
- Call `loadModel()` in `setUpBeforeClass()`
- Assert against real source data
- When adding a new source, create its bootstrap first so the same test files can run against it

### Adding a New Source Type

1. Create `tests/auto/models/config/<SOURCE_MODEL>.php`
2. Define constants:
```php
const SOURCE_TYPE = '<SOURCE_MODEL>';
const DBNAME = 'your_db_name';
// Optional: const DATABASE_FOLDER = '...';
```
3. Add reference data constants (these data will be added for the developer before create the files):
```php
const ACCOUNT_UID_EXAMPLE = {ACC_UID};
const ENTITY_REFERENCE_UID = {ENTITY_UID};
const ENTITY_REFERENCE_NAME = '{PLAYER_NAME}';
const GUILD_REFERENCE_UID = {GUILD_UID};
const GUILD_REFERENCE_NAME = '{GUILD_NAME}';
```

## Adding New Tests

### Model Tests

1. Create `tests/auto/models/<Model>Test.php`
2. Use the existing bootstrap pattern:
```php
<?php
declare(strict_types=1);
require_once 'tests/auto/models/helpers.php';

use PHPUnit\Framework\TestCase;

final class <model>ModelTest extends TestCase
{
  public static function setUpBeforeClass(): void {
    loadModel('account');
  }

  public function testGetByUID(): void {
    $account = AccountModel::getByUID(ACCOUNT_UID_EXAMPLE);
    $this->assertNotNull($account);
  }
}
```


## Testing Patterns

### Test Structure

```php
<?php
declare(strict_types=1);
require_once 'tests/auto/models/helpers.php';

use PHPUnit\Framework\TestCase;

final class accountModelTest extends TestCase
{
  public static function setUpBeforeClass(): void {
    loadModel('account');
  }

  public function testGetByUID(): void {
    $account = AccountModel::getByUID(ACCOUNT_UID_EXAMPLE);
    $this->assertNotNull($account);
  }
}
```

### Test Dependencies

Use `@depends` for ordered tests:

```php
/**
 * @depends testCreateAccount
 */
public function testGetAccountByUsername(): void {
  // ...
}
```


## Integration test pattern

Integration tests extend `IntegrationTestCase` in `tests/auto/integration/IntegrationTestCase.php`.

- Starts a PHP built-in server with `src/` as the document root
- Covers routing, auth, redirects, form handling, and rendered output

When you need to do an integration testing, also read these two documents:

For api methods check [Testing Methods/API](/Docs/testing/api-methods.md).
For integration guide [Integration Testing Docs](/Docs/testing/integration-testing.md).
