import pytest
from app import create_app, db
from app.models import User
from app.config import TestingConfig

@pytest.fixture(scope='session')
def app():
    """Create and configure a Flask app for testing."""
    app = create_app(TestingConfig)
    
    # Create the database and load test data
    with app.app_context():
        db.create_all()
        yield app
        db.session.remove()
        db.drop_all()

@pytest.fixture(scope='session')
def client(app):
    """A test client for the app."""
    return app.test_client()

@pytest.fixture(scope='session')
def runner(app):
    """A test CLI runner for the app."""
    return app.test_cli_runner()

@pytest.fixture(scope='function')
def test_db(app):
    """Create a fresh database for each test."""
    with app.app_context():
        db.create_all()
        yield db
        db.session.remove()
        db.drop_all()

@pytest.fixture
def test_user(app):
    """Create a test user."""
    with app.app_context():
        user = User.create(
            username='testuser',
            email='test@example.com',
            company='Test Company',
            password='Test123!'
        )
        db.session.commit()
        return user

@pytest.fixture
def test_admin(app):
    """Create a test admin user."""
    with app.app_context():
        admin = User.create(
            username='admin',
            email='admin@example.com',
            company='Admin Company',
            password='Admin123!'
        )
        admin.is_admin = True
        db.session.commit()
        return admin

@pytest.fixture
def auth_client(client, test_user):
    """A test client that is authenticated."""
    client.post('/login', data={
        'email': 'test@example.com',
        'password': 'Test123!',
        'remember_me': False
    })
    return client

@pytest.fixture
def admin_client(client, test_admin):
    """A test client that is authenticated as admin."""
    client.post('/login', data={
        'email': 'admin@example.com',
        'password': 'Admin123!',
        'remember_me': False
    })
    return client 