# Contract Tests

API contract tests organized by Django app, with optional workflow tests.

## Testing Modes

Two modes via `CONTRACT_TEST_MODE` environment variable:

| Mode | Command | Description |
|------|---------|-------------|
| **api** (default) | `pytest tests/contracts/` | Fast, Django test client, test DB |
| **live** | `CONTRACT_TEST_MODE=live pytest tests/contracts/` | Real HTTP, LiveServerTestCase, test DB |

### Mode Comparison

| | `api` (default) | `live` |
|---|---|---|
| **Base class** | `APITestCase` | `LiveServerTestCase` |
| **HTTP** | In-process (Django test client) | Real HTTP via `requests` |
| **Auth** | `force_authenticate()` | JWT tokens via API |
| **Database** | Django test DB (isolated) | Django test DB (isolated) |
| **Speed** | ~3-5 sec | ~15-30 sec |
| **Server** | None (in-process) | Auto-started by Django |

### Key Point: Both Modes Use Test Database

Neither mode touches your real database. Django automatically:
1. Creates a test database (prefixed with `test_`)
2. Runs migrations
3. Destroys it after tests complete

## File Structure

```
tests/contracts/
├── base.py              # Mode switcher (imports from base_api or base_live)
├── base_api.py          # APITestCase implementation
├── base_live.py         # LiveServerTestCase implementation
├── conftest.py          # pytest-django configuration
├── endpoints.py         # API paths (single source of truth)
├── helpers.py           # Shared test data helpers
│
├── mascotas/            # Django app: mascotas
│   ├── test_pet_owners.py
│   ├── test_pets.py
│   └── test_coverage.py
│
├── productos/           # Django app: productos
│   ├── test_services.py
│   └── test_cart.py
│
├── solicitudes/         # Django app: solicitudes
│   └── test_service_requests.py
│
└── workflows/           # Multi-step API sequences (e.g., turnero booking flow)
    └── test_turnero_general.py
```

## Running Tests

```bash
# All contract tests
pytest tests/contracts/

# Single app
pytest tests/contracts/mascotas/

# Single file
pytest tests/contracts/mascotas/test_pet_owners.py

# Live mode (real HTTP)
CONTRACT_TEST_MODE=live pytest tests/contracts/
```
