"""模型单元测试""" import pytest from datetime import datetime from app.models.domain import ProxyRaw, Proxy, PluginInfo from app.models.schemas import ( ProxyCreate, ProxyListRequest, SettingsSchema, BatchDeleteRequest, ) class TestProxyRaw: """测试 ProxyRaw 领域模型""" def test_create_proxy_raw(self): """测试创建原始代理""" proxy = ProxyRaw("192.168.1.1", 8080, "http") assert proxy.ip == "192.168.1.1" assert proxy.port == 8080 assert proxy.protocol == "http" def test_protocol_normalization(self): """测试协议标准化""" proxy = ProxyRaw("192.168.1.1", 8080, "HTTP") assert proxy.protocol == "http" def test_invalid_protocol_defaults_to_http(self): """测试无效协议默认为 http""" proxy = ProxyRaw("192.168.1.1", 8080, "invalid") assert proxy.protocol == "http" class TestProxy: """测试 Proxy 领域模型""" def test_create_proxy(self): """测试创建代理实体""" proxy = Proxy( ip="192.168.1.1", port=8080, protocol="http", score=50, response_time_ms=100.5, last_check=datetime.now(), created_at=datetime.now(), ) assert proxy.ip == "192.168.1.1" assert proxy.score == 50 class TestPluginInfo: """测试 PluginInfo 领域模型""" def test_create_plugin_info(self): """测试创建插件信息""" plugin = PluginInfo( id="test_plugin", name="test_plugin", display_name="测试插件", description="用于测试", enabled=True, success_count=10, failure_count=2, ) assert plugin.id == "test_plugin" assert plugin.enabled is True assert plugin.success_count == 10 class TestProxyCreateSchema: """测试 ProxyCreate Pydantic 模型""" def test_valid_proxy_create(self): """测试有效的代理创建""" proxy = ProxyCreate(ip="192.168.1.1", port=8080, protocol="http") assert proxy.ip == "192.168.1.1" assert proxy.port == 8080 def test_port_validation(self): """测试端口验证""" with pytest.raises(Exception): ProxyCreate(ip="192.168.1.1", port=70000) # 超出范围 def test_protocol_validation(self): """测试协议验证""" with pytest.raises(Exception): ProxyCreate(ip="192.168.1.1", port=8080, protocol="invalid") class TestProxyListRequest: """测试 ProxyListRequest 模式""" def test_default_values(self): """测试默认值""" request = ProxyListRequest() assert request.page == 1 assert request.page_size == 20 assert request.sort_by == "last_check" assert request.sort_order == "DESC" def test_custom_values(self): """测试自定义值""" request = ProxyListRequest(page=2, page_size=50, protocol="https") assert request.page == 2 assert request.page_size == 50 assert request.protocol == "https" def test_pool_filter_pending_available(self): r1 = ProxyListRequest(pool_filter="pending") assert r1.pool_filter == "pending" r2 = ProxyListRequest(pool_filter="all") assert r2.pool_filter is None with pytest.raises(Exception): ProxyListRequest(pool_filter="invalid") class TestSettingsSchema: """测试 SettingsSchema""" def test_default_settings(self): """测试默认设置""" settings = SettingsSchema() assert settings.validation_timeout == 6 assert settings.default_concurrency == 120 assert settings.auto_validate is True assert settings.auto_validate_after_crawl is False def test_custom_settings(self): """测试自定义设置""" settings = SettingsSchema(validation_timeout=25, auto_validate=False) assert settings.validation_timeout == 25 assert settings.auto_validate is False def test_settings_schema_ignores_unknown_fields(self): s = SettingsSchema.model_validate({"validation_timeout": 10, "crawl_timeout": 99}) assert "crawl_timeout" not in s.model_dump() assert s.validation_timeout == 10 class TestBatchDeleteRequest: """测试 BatchDeleteRequest""" def test_valid_batch_delete(self): """测试有效的批量删除""" request = BatchDeleteRequest(proxies=[ {"ip": "192.168.1.1", "port": 8080}, {"ip": "192.168.1.2", "port": 8081}, ]) assert len(request.proxies) == 2