2026-08-14 18:02:25 +02:00
|
|
|
import os
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
from uuid import uuid4
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
# Base de test dediee (ne pas toucher a gmao_db)
|
|
|
|
|
project_root = Path(__file__).resolve().parents[1]
|
|
|
|
|
docker_env = {}
|
|
|
|
|
docker_env_file = project_root / '.env.docker'
|
|
|
|
|
if not os.environ.get('DATABASE_URL') and docker_env_file.exists():
|
|
|
|
|
for raw_line in docker_env_file.read_text(encoding='utf-8').splitlines():
|
|
|
|
|
if raw_line and not raw_line.startswith('#') and '=' in raw_line:
|
|
|
|
|
key, value = raw_line.split('=', 1)
|
|
|
|
|
docker_env[key] = value
|
|
|
|
|
os.environ['DATABASE_URL'] = (
|
|
|
|
|
f"mysql+pymysql://{docker_env.get('MARIADB_USER', 'gmao')}:"
|
|
|
|
|
f"{docker_env['MARIADB_PASSWORD']}@127.0.0.1:3307/gmao_test_db?charset=utf8mb4"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if not os.environ.get('DATABASE_URL'):
|
|
|
|
|
raise RuntimeError('DATABASE_URL de test manquante')
|
|
|
|
|
os.environ.setdefault('SECRET_KEY', 'test-secret-key-with-at-least-32-characters')
|
|
|
|
|
os.environ.setdefault('OUTLOOK_ENCRYPTION_KEY', 'S1Baix4126-5QfNnofmCV5qKqrMMvBoJj7MZ6WVFpQE=')
|
|
|
|
|
os.environ.setdefault('SETUP_TOKEN', 'test-setup-token-with-at-least-32-characters')
|
|
|
|
|
|
|
|
|
|
from app_new import create_app, db
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
|
def app():
|
|
|
|
|
app = create_app('testing')
|
|
|
|
|
with app.app_context():
|
|
|
|
|
db.drop_all()
|
|
|
|
|
db.create_all()
|
2026-08-21 18:46:19 +02:00
|
|
|
# Le runtime ne lit plus User.role. Le bootstrap de test reproduit la
|
|
|
|
|
# migration RBAC en créant explicitement les rôles et leurs permissions.
|
|
|
|
|
from app_new.core.authorization import PERMISSIONS_BY_ROLE, ROLE_LABELS
|
|
|
|
|
from app_new.core.models.rbac import Role, Permission, RolePermission
|
|
|
|
|
permissions_by_code = {}
|
|
|
|
|
for slug, codes in PERMISSIONS_BY_ROLE.items():
|
|
|
|
|
role = Role(slug=slug, name=ROLE_LABELS.get(slug, slug), is_system=True)
|
|
|
|
|
db.session.add(role)
|
|
|
|
|
db.session.flush()
|
|
|
|
|
for code in codes:
|
|
|
|
|
permission = permissions_by_code.get(code)
|
|
|
|
|
if permission is None:
|
|
|
|
|
permission = Permission(code=code, name=code, module=code.split('.', 1)[0], action=code.split('.', 1)[1] if '.' in code else 'all')
|
|
|
|
|
db.session.add(permission)
|
|
|
|
|
db.session.flush()
|
|
|
|
|
permissions_by_code[code] = permission
|
|
|
|
|
db.session.add(RolePermission(role_id=role.id, permission_id=permission.id, effect='allow'))
|
|
|
|
|
db.session.commit()
|
2026-08-14 18:02:25 +02:00
|
|
|
yield app
|
|
|
|
|
with app.app_context():
|
|
|
|
|
db.session.remove()
|
|
|
|
|
db.drop_all()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
|
def _db(app):
|
|
|
|
|
return db
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def client(app):
|
|
|
|
|
return app.test_client()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def admin_user(app):
|
|
|
|
|
from app_new.core.models.user import User
|
|
|
|
|
|
|
|
|
|
with app.app_context():
|
|
|
|
|
username = f'test_admin_{uuid4().hex[:8]}'
|
|
|
|
|
password = 'test-password-strong'
|
|
|
|
|
user = User(
|
|
|
|
|
username=username,
|
|
|
|
|
email=f'{username}@gmao.local',
|
|
|
|
|
full_name='Administrateur de test',
|
|
|
|
|
role='admin',
|
|
|
|
|
is_active=True,
|
|
|
|
|
)
|
|
|
|
|
user.set_password(password)
|
|
|
|
|
db.session.add(user)
|
2026-08-21 18:46:19 +02:00
|
|
|
db.session.flush()
|
|
|
|
|
from app_new.core.models.rbac import Role, UserRole
|
|
|
|
|
admin_role = Role.query.filter_by(slug='admin', is_active=True).first()
|
|
|
|
|
db.session.add(UserRole(user_id=user.id, role_id=admin_role.id))
|
2026-08-14 18:02:25 +02:00
|
|
|
db.session.commit()
|
|
|
|
|
user_id = user.id
|
|
|
|
|
yield {'id': user_id, 'username': username, 'password': password}
|
|
|
|
|
with app.app_context():
|
|
|
|
|
user = db.session.get(User, user_id)
|
|
|
|
|
if user:
|
|
|
|
|
db.session.delete(user)
|
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def authenticated_client(client, admin_user):
|
|
|
|
|
response = client.post('/auth/login', data={
|
|
|
|
|
'username': admin_user['username'],
|
|
|
|
|
'password': admin_user['password'],
|
|
|
|
|
})
|
|
|
|
|
assert response.status_code == 302
|
|
|
|
|
return client
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def runner(app):
|
|
|
|
|
return app.test_cli_runner()
|