"""
认证 API 单元测试
"""
import pytest
from app import create_app
from app.extensions import db
from app.models import User
from app.utils.security import hash_password


@pytest.fixture
def app():
    """创建测试应用"""
    app = create_app('testing')
    with app.app_context():
        db.create_all()
        yield app
        db.drop_all()


@pytest.fixture
def client(app):
    """创建测试客户端"""
    return app.test_client()


class TestAuthAPI:
    """认证 API 测试"""
    
    def test_register_success(self, client):
        """测试用户注册成功"""
        response = client.post('/api/auth/register', json={
            'username': 'testuser',
            'email': 'test@example.com',
            'password': 'password123',
            'nickname': 'Test User'
        })
        
        assert response.status_code == 201
        data = response.get_json()
        assert data['user']['username'] == 'testuser'
        assert data['user']['email'] == 'test@example.com'
    
    def test_register_duplicate_username(self, client, app):
        """测试重复用户名"""
        # 创建已存在的用户
        with app.app_context():
            user = User(
                username='testuser',
                email='existing@example.com',
                password_hash=hash_password('password')
            )
            db.session.add(user)
            db.session.commit()
        
        # 尝试注册相同用户名
        response = client.post('/api/auth/register', json={
            'username': 'testuser',
            'email': 'new@example.com',
            'password': 'password123'
        })
        
        assert response.status_code == 400
    
    def test_register_missing_fields(self, client):
        """测试缺少必填字段"""
        response = client.post('/api/auth/register', json={
            'username': 'testuser'
        })
        
        assert response.status_code == 400
    
    def test_login_success(self, client, app):
        """测试登录成功"""
        # 创建用户
        with app.app_context():
            user = User(
                username='testuser',
                email='test@example.com',
                password_hash=hash_password('password123')
            )
            db.session.add(user)
            db.session.commit()
        
        # 登录
        response = client.post('/api/auth/login', json={
            'username': 'testuser',
            'password': 'password123'
        })
        
        assert response.status_code == 200
        data = response.get_json()
        assert 'access_token' in data
        assert 'refresh_token' in data
    
    def test_login_invalid_credentials(self, client):
        """测试无效凭据"""
        response = client.post('/api/auth/login', json={
            'username': 'nonexistent',
            'password': 'wrong'
        })
        
        assert response.status_code == 401
    
    def test_verify_token(self, client, app):
        """测试 Token 验证"""
        # 创建用户
        with app.app_context():
            user = User(
                username='testuser',
                email='test@example.com',
                password_hash=hash_password('password123')
            )
            db.session.add(user)
            db.session.commit()
        
        # 登录获取 token
        login_response = client.post('/api/auth/login', json={
            'username': 'testuser',
            'password': 'password123'
        })
        token = login_response.get_json()['access_token']
        
        # 验证 token
        response = client.post('/api/auth/verify', headers={
            'Authorization': f'Bearer {token}'
        })
        
        assert response.status_code == 200
        data = response.get_json()
        assert data['valid'] is True


class TestValidation:
    """验证测试"""
    
    def test_validate_email(self, client):
        """测试邮箱验证"""
        from app.utils.validators import validate_email
        
        assert validate_email('test@example.com') is True
        assert validate_email('invalid-email') is False
    
    def test_validate_username(self, client):
        """测试用户名验证"""
        from app.utils.validators import validate_username
        
        assert validate_username('testuser') is True
        assert validate_username('ab') is False  # 太短
        assert validate_username('test-user') is True
        assert validate_username('test@user') is False  # 包含非法字符
    
    def test_validate_uuid(self, client):
        """测试 UUID 验证"""
        from app.utils.validators import validate_uuid
        
        assert validate_uuid('550e8400-e29b-41d4-a716-446655440000') is True
        assert validate_uuid('invalid-uuid') is False
