feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,300 @@
|
||||
"""
|
||||
测试验证引擎模块
|
||||
"""
|
||||
|
||||
from typing import Dict, Any, Tuple, Optional
|
||||
import re
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
class ValidationEngine:
|
||||
"""测试验证引擎"""
|
||||
|
||||
@staticmethod
|
||||
def validate_status_code(expected: int, actual: int) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证HTTP状态码
|
||||
|
||||
Args:
|
||||
expected: 期望的状态码
|
||||
actual: 实际的状态码
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
if expected == actual:
|
||||
return True, ""
|
||||
return False, f"期望状态码{expected},实际{actual}"
|
||||
|
||||
@staticmethod
|
||||
def validate_response_body(expected: Dict[str, Any], actual: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证响应体
|
||||
|
||||
Args:
|
||||
expected: 期望的响应体
|
||||
actual: 实际的响应体
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
if expected == actual:
|
||||
return True, ""
|
||||
|
||||
# 找出差异
|
||||
differences = ValidationEngine._find_differences(expected, actual)
|
||||
return False, f"响应体不匹配: {differences}"
|
||||
|
||||
@staticmethod
|
||||
def validate_contains(expected_value: Any, actual_value: Any) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证包含关系
|
||||
|
||||
Args:
|
||||
expected_value: 期望包含的值
|
||||
actual_value: 实际值
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
if isinstance(actual_value, (str, list, dict)):
|
||||
if expected_value in actual_value:
|
||||
return True, ""
|
||||
return False, f"期望值'{expected_value}'不在实际值中"
|
||||
|
||||
if expected_value == actual_value:
|
||||
return True, ""
|
||||
return False, f"期望包含'{expected_value}',实际为'{actual_value}'"
|
||||
|
||||
@staticmethod
|
||||
def validate_equals(expected_value: Any, actual_value: Any) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证相等关系
|
||||
|
||||
Args:
|
||||
expected_value: 期望的值
|
||||
actual_value: 实际的值
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
if expected_value == actual_value:
|
||||
return True, ""
|
||||
return False, f"期望值'{expected_value}',实际值'{actual_value}'"
|
||||
|
||||
@staticmethod
|
||||
def validate_json_path(path: str, expected_value: Any, actual_data: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证JSON路径
|
||||
|
||||
Args:
|
||||
path: JSON路径(如"data.user.id")
|
||||
expected_value: 期望的值
|
||||
actual_data: 实际的数据
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
try:
|
||||
keys = path.split('.')
|
||||
value = actual_data
|
||||
|
||||
for key in keys:
|
||||
if isinstance(value, dict):
|
||||
value = value.get(key)
|
||||
elif isinstance(value, list) and key.isdigit():
|
||||
value = value[int(key)]
|
||||
else:
|
||||
return False, f"路径'{path}'不存在"
|
||||
|
||||
if value == expected_value:
|
||||
return True, ""
|
||||
return False, f"路径'{path}'期望值'{expected_value}',实际值'{value}'"
|
||||
|
||||
except Exception as e:
|
||||
return False, f"验证JSON路径失败: {str(e)}"
|
||||
|
||||
@staticmethod
|
||||
def validate_regex(pattern: str, actual_value: str) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证正则表达式
|
||||
|
||||
Args:
|
||||
pattern: 正则表达式模式
|
||||
actual_value: 实际的值
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
try:
|
||||
if re.match(pattern, str(actual_value)):
|
||||
return True, ""
|
||||
return False, f"值'{actual_value}'不匹配正则表达式'{pattern}'"
|
||||
except Exception as e:
|
||||
return False, f"正则表达式验证失败: {str(e)}"
|
||||
|
||||
@staticmethod
|
||||
def validate_header(expected_header: Dict[str, str], actual_headers: Dict[str, str]) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证响应头
|
||||
|
||||
Args:
|
||||
expected_header: 期望的响应头
|
||||
actual_headers: 实际的响应头
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
for key, expected_value in expected_header.items():
|
||||
actual_value = actual_headers.get(key)
|
||||
if actual_value is None:
|
||||
return False, f"缺少响应头: {key}"
|
||||
if actual_value != expected_value:
|
||||
return False, f"响应头'{key}'期望值'{expected_value}',实际值'{actual_value}'"
|
||||
|
||||
return True, ""
|
||||
|
||||
@staticmethod
|
||||
def validate_response_time(expected_max_time: float, actual_time: float) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证响应时间
|
||||
|
||||
Args:
|
||||
expected_max_time: 期望的最大响应时间(毫秒)
|
||||
actual_time: 实际的响应时间(毫秒)
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
if actual_time <= expected_max_time:
|
||||
return True, ""
|
||||
return False, f"响应时间{actual_time}ms超过期望最大值{expected_max_time}ms"
|
||||
|
||||
@staticmethod
|
||||
def validate_schema(expected_schema: Dict[str, Any], actual_data: Dict[str, Any]) -> Tuple[bool, str]:
|
||||
"""
|
||||
验证数据结构
|
||||
|
||||
Args:
|
||||
expected_schema: 期望的结构(简化版)
|
||||
actual_data: 实际的数据
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
for key, expected_type in expected_schema.items():
|
||||
if key not in actual_data:
|
||||
return False, f"缺少字段: {key}"
|
||||
|
||||
actual_value = actual_data[key]
|
||||
|
||||
if expected_type == "string" and not isinstance(actual_value, str):
|
||||
return False, f"字段'{key}'期望类型string,实际类型{type(actual_value).__name__}"
|
||||
elif expected_type == "number" and not isinstance(actual_value, (int, float)):
|
||||
return False, f"字段'{key}'期望类型number,实际类型{type(actual_value).__name__}"
|
||||
elif expected_type == "boolean" and not isinstance(actual_value, bool):
|
||||
return False, f"字段'{key}'期望类型boolean,实际类型{type(actual_value).__name__}"
|
||||
elif expected_type == "array" and not isinstance(actual_value, list):
|
||||
return False, f"字段'{key}'期望类型array,实际类型{type(actual_value).__name__}"
|
||||
elif expected_type == "object" and not isinstance(actual_value, dict):
|
||||
return False, f"字段'{key}'期望类型object,实际类型{type(actual_value).__name__}"
|
||||
|
||||
return True, ""
|
||||
|
||||
@staticmethod
|
||||
def _find_differences(expected: Any, actual: Any, path: str = "") -> str:
|
||||
"""
|
||||
找出两个值之间的差异
|
||||
|
||||
Args:
|
||||
expected: 期望的值
|
||||
actual: 实际的值
|
||||
path: 当前路径
|
||||
|
||||
Returns:
|
||||
差异描述
|
||||
"""
|
||||
if expected == actual:
|
||||
return ""
|
||||
|
||||
if isinstance(expected, dict) and isinstance(actual, dict):
|
||||
differences = []
|
||||
|
||||
all_keys = set(expected.keys()) | set(actual.keys())
|
||||
|
||||
for key in all_keys:
|
||||
new_path = f"{path}.{key}" if path else key
|
||||
|
||||
if key not in expected:
|
||||
differences.append(f"{new_path}: 实际存在但期望不存在")
|
||||
elif key not in actual:
|
||||
differences.append(f"{new_path}: 期望存在但实际不存在")
|
||||
else:
|
||||
diff = ValidationEngine._find_differences(expected[key], actual[key], new_path)
|
||||
if diff:
|
||||
differences.append(diff)
|
||||
|
||||
return "; ".join(differences)
|
||||
|
||||
elif isinstance(expected, list) and isinstance(actual, list):
|
||||
if len(expected) != len(actual):
|
||||
return f"{path}: 长度不匹配(期望{len(expected)},实际{len(actual)})"
|
||||
|
||||
differences = []
|
||||
for i, (exp_item, act_item) in enumerate(zip(expected, actual)):
|
||||
new_path = f"{path}[{i}]"
|
||||
diff = ValidationEngine._find_differences(exp_item, act_item, new_path)
|
||||
if diff:
|
||||
differences.append(diff)
|
||||
|
||||
return "; ".join(differences)
|
||||
|
||||
else:
|
||||
return f"{path}: 期望'{expected}',实际'{actual}'"
|
||||
|
||||
|
||||
class ValidationRule:
|
||||
"""验证规则"""
|
||||
|
||||
def __init__(self, rule_type: str, expected_value: Any = None, path: str = None):
|
||||
"""
|
||||
初始化验证规则
|
||||
|
||||
Args:
|
||||
rule_type: 规则类型(status_code, contains, equals, json_path, regex, header, response_time, schema)
|
||||
expected_value: 期望值
|
||||
path: JSON路径(仅用于json_path规则)
|
||||
"""
|
||||
self.rule_type = rule_type
|
||||
self.expected_value = expected_value
|
||||
self.path = path
|
||||
|
||||
def validate(self, actual_value: Any = None, actual_data: Dict[str, Any] = None) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行验证
|
||||
|
||||
Args:
|
||||
actual_value: 实际值
|
||||
actual_data: 实际数据(用于JSON路径验证)
|
||||
|
||||
Returns:
|
||||
(是否通过, 错误消息)
|
||||
"""
|
||||
if self.rule_type == "status_code":
|
||||
return ValidationEngine.validate_status_code(self.expected_value, actual_value)
|
||||
elif self.rule_type == "contains":
|
||||
return ValidationEngine.validate_contains(self.expected_value, actual_value)
|
||||
elif self.rule_type == "equals":
|
||||
return ValidationEngine.validate_equals(self.expected_value, actual_value)
|
||||
elif self.rule_type == "json_path":
|
||||
return ValidationEngine.validate_json_path(self.path, self.expected_value, actual_data)
|
||||
elif self.rule_type == "regex":
|
||||
return ValidationEngine.validate_regex(self.expected_value, actual_value)
|
||||
elif self.rule_type == "header":
|
||||
return ValidationEngine.validate_header(self.expected_value, actual_value)
|
||||
elif self.rule_type == "response_time":
|
||||
return ValidationEngine.validate_response_time(self.expected_value, actual_value)
|
||||
elif self.rule_type == "schema":
|
||||
return ValidationEngine.validate_schema(self.expected_value, actual_data)
|
||||
else:
|
||||
return False, f"未知的验证规则类型: {self.rule_type}"
|
||||
Reference in New Issue
Block a user