Files
ENI-projet-piscine/apps/backend/tests/factories.py
T
Johan LEROY a8f59e6e76 feat(backend): ajoute les comptes applicatifs et l'amorçage du premier admin
Table `app_user`, son dépôt, et la commande `create-admin`. Le nom évite
`user`, mot réservé de PostgreSQL, et rappelle qu'il s'agit d'un compte
applicatif, par opposition au rôle PostgreSQL qui portera le
cantonnement des accès ETL et ML.

`credentials_changed_at` couvre à elle seule le changement de mot de
passe, le changement de rôle et la désactivation : tout jeton émis avant
cet instant sera refusé, sans attendre son expiration.

La configuration refuse désormais de démarrer sur cinq erreurs
silencieuses : secret trop court ou laissé à sa valeur d'exemple, `debug`
en production, joker CORS, origines vides hors local, et cookie
`SameSite=None` sans `Secure`. Les fixtures de test et les deux
`.env.example` suivent, sans quoi rien ne démarrerait.

Le mot de passe de l'admin ne transite jamais par `argv`, visible de tout
`ps` : il est saisi par `getpass` ou tiré au sort. Une révision Alembic
qui insérerait ce compte graverait son empreinte dans Git pour toujours.
2026-09-15 14:30:05 +02:00

38 lines
1.2 KiB
Python

from typing import Any
from app.core.config import Settings
SETTINGS_DE_TEST: dict[str, Any] = {
"env": "local",
"debug": False,
"log_level": "WARNING",
"cors_origins": "",
"secret_key": "secret-de-test-assez-long-pour-le-validateur",
"database_url": "postgresql+asyncpg://enervision:change_me@localhost:5433/enervision_test",
}
class FakeSession:
"""Session factice : renvoie `result`, ou leve `failure` si elle est fournie."""
def __init__(self, result: object = None, failure: Exception | None = None) -> None:
self._result = result
self._failure = failure
async def scalar(self, *_: object, **__: object) -> object:
return self._repondre()
async def execute(self, *_: object, **__: object) -> object:
return self._repondre()
def _repondre(self) -> object:
if self._failure is not None:
raise self._failure
return self._result
# Piège : les arguments nommés priment sur l'environnement et sur .env, contrairement
# aux variables posées par la fixture `environment`, qui restent surchargeables.
def make_settings(**overrides: Any) -> Settings:
return Settings(**{**SETTINGS_DE_TEST, **overrides})