""" 测试工具函数和配置 """ import pytest from datetime import datetime from pathlib import Path import sys import os project_root = Path(__file__).parent.parent.absolute() sys.path.insert(0, str(project_root)) os.chdir(project_root) from app.utils import make_response, register_cors from app.settings import config class TestMakeResponse: """测试 make_response 工具函数""" def test_make_response_default_success(self): """测试默认成功响应""" response = make_response() assert response['status'] == 'success' assert response['message'] == '操作成功' assert response['data'] == {} assert response['errors'] == [] assert 'timestamp' in response def test_make_response_custom_status(self): """测试自定义状态""" response = make_response(status='error') assert response['status'] == 'error' assert response['message'] == '操作失败' def test_make_response_custom_message(self): """测试自定义消息""" response = make_response(message='自定义消息') assert response['message'] == '自定义消息' def test_make_response_with_data(self): """测试带数据的响应""" test_data = {'key': 'value', 'number': 42} response = make_response(data=test_data) assert response['data'] == test_data def test_make_response_with_errors(self): """测试带错误的响应""" errors = ['错误 1', '错误 2'] response = make_response(errors=errors) assert response['errors'] == errors assert len(response['errors']) == 2 def test_make_response_with_extra(self): """测试带额外信息的响应""" extra = {'extra_key': 'extra_value'} response = make_response(extra=extra) assert response['extra_key'] == 'extra_value' def test_make_response_timestamp_format(self): """测试时间戳格式""" response = make_response() timestamp = response['timestamp'] # 验证 ISO 8601 格式 assert 'T' in timestamp assert 'Z' in timestamp # 验证可以解析 try: datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ') except ValueError: pytest.fail("时间戳格式不正确") def test_make_response_combined(self): """测试组合响应""" response = make_response( status='success', message='测试消息', data={'result': 'ok'}, errors=[], extra={'page': 1} ) assert response['status'] == 'success' assert response['message'] == '测试消息' assert response['data']['result'] == 'ok' assert response['errors'] == [] assert response['page'] == 1 class TestRegisterCORS: """测试 CORS 注册""" def test_register_cors_sets_headers(self): """测试 CORS 设置正确的头""" from flask import Flask app = Flask(__name__) register_cors(app) # 验证注册了 after_request 处理器 assert len(app.after_request_funcs) > 0 def test_register_cors_options_route(self): """测试 OPTIONS 路由注册""" from flask import Flask app = Flask(__name__) register_cors(app) rules = [rule.rule for rule in app.url_map.iter_rules()] assert '/config' in rules class TestConfig: """测试配置模块""" def test_config_is_dict(self): """测试配置是字典""" assert isinstance(config, dict) def test_config_max_content_length(self): """测试最大内容长度配置""" assert 'MAX_CONTENT_LENGTH' in config assert config['MAX_CONTENT_LENGTH'] == 500 * 1024 * 1024 # 500MB def test_config_send_file_max_age(self): """测试文件发送最大年龄配置""" assert 'SEND_FILE_MAX_AGE_DEFAULT' in config assert config['SEND_FILE_MAX_AGE_DEFAULT'] == 300 # 300 秒 def test_config_input_dir(self): """测试输入目录配置""" assert 'INPUT_DIR' in config assert config['INPUT_DIR'] == 'input' def test_config_output_dir(self): """测试输出目录配置""" assert 'OUTPUT_DIR' in config assert config['OUTPUT_DIR'] == 'output' def test_config_task_timeout(self): """测试任务超时配置""" assert 'TASK_TIMEOUT' in config assert config['TASK_TIMEOUT'] == 600 # 600 秒 def test_config_api_port(self): """测试 API 端口配置""" assert 'API_PORT' in config assert config['API_PORT'] == 5000 assert isinstance(config['API_PORT'], int) assert config['API_PORT'] > 0 def test_config_video_port(self): """测试视频端口配置""" assert 'VIDEO_PORT' in config assert config['VIDEO_PORT'] == 8086 assert isinstance(config['VIDEO_PORT'], int) assert config['VIDEO_PORT'] > 0 def test_config_all_required_keys(self): """测试所有必需的键""" required_keys = [ 'MAX_CONTENT_LENGTH', 'SEND_FILE_MAX_AGE_DEFAULT', 'INPUT_DIR', 'OUTPUT_DIR', 'TASK_TIMEOUT', 'API_PORT', 'VIDEO_PORT' ] for key in required_keys: assert key in config, f"配置缺少必需的键:{key}" def test_config_no_extra_keys(self): """测试没有多余的键(可选)""" allowed_keys = [ 'MAX_CONTENT_LENGTH', 'SEND_FILE_MAX_AGE_DEFAULT', 'INPUT_DIR', 'OUTPUT_DIR', 'TASK_TIMEOUT', 'API_PORT', 'VIDEO_PORT' ] for key in config.keys(): assert key in allowed_keys, f"配置包含未预期的键:{key}" class TestResponseFormat: """测试响应格式规范""" def test_response_has_required_fields(self): """测试响应包含必需字段""" response = make_response() required_fields = ['status', 'data', 'errors', 'message', 'timestamp'] for field in required_fields: assert field in response, f"响应缺少必需字段:{field}" def test_response_status_values(self): """测试响应状态值""" valid_statuses = ['success', 'error'] for status in valid_statuses: response = make_response(status=status) assert response['status'] == status def test_response_data_is_dict(self): """测试数据字段是字典""" response = make_response() assert isinstance(response['data'], dict) def test_response_errors_is_list(self): """测试错误字段是列表""" response = make_response() assert isinstance(response['errors'], list) def test_response_message_is_string(self): """测试消息字段是字符串""" response = make_response() assert isinstance(response['message'], str) def test_response_timestamp_is_string(self): """测试时间戳字段是字符串""" response = make_response() assert isinstance(response['timestamp'], str) if __name__ == '__main__': pytest.main([__file__, '-v'])