"""Pytest configuration and fixtures for shopdb-flask. Strategy: in-memory SQLite via StaticPool (configured in TestingConfig) so the database is shared across the connection. Each test drops and recreates the schema. Simple, totally isolated, fast enough for a small schema. Switch to savepoint-per-test if test count grows past a few hundred. """ import os import pytest from werkzeug.security import generate_password_hash # Force testing config before any shopdb import touches the env. os.environ['FLASK_ENV'] = 'testing' from shopdb import create_app from shopdb.extensions import db as _db @pytest.fixture(scope='session') def app(): """Create the Flask application for the test session.""" application = create_app('testing') return application @pytest.fixture(scope='function') def db(app): """Provide a fresh database per test. Drops and recreates schema each run.""" with app.app_context(): _db.create_all() yield _db _db.session.remove() _db.drop_all() @pytest.fixture def client(app): """Flask test client.""" return app.test_client() @pytest.fixture def runner(app): """Flask CLI test runner.""" return app.test_cli_runner() @pytest.fixture def admin_user(db): """Create an admin user for authenticated tests. The user has username 'testadmin' and password 'testpass'. """ from shopdb.core.models import User, Role role = Role(rolename='admin', description='Administrator') db.session.add(role) db.session.flush() user = User( username='testadmin', email='admin@test.local', passwordhash=generate_password_hash('testpass'), ) user.roles.append(role) db.session.add(user) db.session.commit() return user @pytest.fixture def auth_headers(client, admin_user): """Log in as admin_user and return Authorization headers.""" response = client.post( '/api/auth/login', json={'username': 'testadmin', 'password': 'testpass'}, ) assert response.status_code == 200, f'Login failed: {response.get_json()}' payload = response.get_json() token = payload['data']['access_token'] return {'Authorization': f'Bearer {token}'}