import importlib import os import sys from pathlib import Path import pytest from werkzeug.security import generate_password_hash ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / 'po_app')) PASSWORD = 'Test-only-Password-2026' @pytest.fixture(scope='session') def module(tmp_path_factory): os.environ['PO_DATA_DIR'] = str(tmp_path_factory.mktemp('po-data')) os.environ.pop('PO_SECRET_KEY', None) result = importlib.import_module('app') result.app.config['TESTING'] = True yield result result.engine.dispose() @pytest.fixture def app(module): from models import Base Base.metadata.drop_all(module.engine) Base.metadata.create_all(module.engine) hashed = generate_password_hash(PASSWORD) with module.Session() as db: for name, role in [('admin', 'admin'), ('maker', 'maker'), ('other', 'maker'), ('reviewer', 'approver'), ('approver', 'approver')]: db.add(module.User(username=name, name=name, role=role, active=True, session_version=1, must_change_password=False, password_hash=hashed)) db.commit() return module def post(client, path, data=None, **kwargs): with client.session_transaction() as sess: token = sess.get('csrf_token') if not token: client.get('/login') with client.session_transaction() as sess: token = sess['csrf_token'] if data is None: data = {} data = data.copy() data['csrf_token'] = token return client.post(path, data=data, **kwargs) def login(app, name): client = app.app.test_client() client.get('/login') response = post(client, '/login', {'username': name, 'password': PASSWORD}) assert response.status_code == 302 client.get(response.location) return client @pytest.fixture def clients(app): return {name: login(app, name) for name in ('admin', 'maker', 'other', 'reviewer', 'approver')}