test: 补充单元测试并修复 urlencoding 解码 bug
- auth.rs 新增 JWT 生成/验证回环、篡改拒绝、refresh token 随机性、临时 token 有效期测试 - payment.rs 新增套餐定义、URL 解码、支付宝表单解析(UTF-8/GBK)、RSA2 签名验签、UA 检测测试 - 修复 urlencoding 两个真实 bug:UTF-8 多字节序列乱码、不完整转义吞字符 - 移除 db.rs 悬空 doc 注释,修复 auth.rs 冗余引用(clippy 0 警告) - cargo test 从 2 个增至 36 个全过 - 同步 IMPROVEMENTS.md(索引/重复查询/测试覆盖/公告系统状态)
This commit is contained in:
68
src/auth.rs
68
src/auth.rs
@@ -124,3 +124,71 @@ pub fn verify_temp_token(token: &str, secret: &str) -> Result<TempTokenClaims, S
|
||||
|
||||
Ok(decoded.claims)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_SECRET: &str = "unit-test-secret-0123456789";
|
||||
|
||||
#[test]
|
||||
fn test_generate_and_verify_token_roundtrip() {
|
||||
let token = generate_token(42, "openid_test_123", 2, TEST_SECRET).unwrap();
|
||||
|
||||
let claims = verify_token(&token, TEST_SECRET).unwrap();
|
||||
assert_eq!(claims.user_id, 42);
|
||||
assert_eq!(claims.openid, "openid_test_123");
|
||||
assert_eq!(claims.user_type, 2);
|
||||
assert!(claims.exp > claims.iat, "过期时间应晚于签发时间");
|
||||
assert!(claims.exp > Utc::now().timestamp(), "令牌应未过期");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_token_rejects_wrong_secret() {
|
||||
let token = generate_token(42, "openid", 2, TEST_SECRET).unwrap();
|
||||
assert!(verify_token(&token, "wrong-secret").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_token_rejects_tampered_payload() {
|
||||
let token = generate_token(42, "openid", 2, TEST_SECRET).unwrap();
|
||||
|
||||
// 篡改 token 的载荷部分(第 2 段),应验证失败
|
||||
let mut parts: Vec<&str> = token.split('.').collect();
|
||||
assert_eq!(parts.len(), 3);
|
||||
parts[1] = "eyJ1c2VyX2lkIjo5OTl9";
|
||||
let tampered = parts.join(".");
|
||||
assert!(verify_token(&tampered, TEST_SECRET).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_token_rejects_garbage() {
|
||||
assert!(verify_token("not-a-jwt", TEST_SECRET).is_err());
|
||||
assert!(verify_token("", TEST_SECRET).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_refresh_token_is_random_uuid() {
|
||||
let a = generate_refresh_token(1, TEST_SECRET).unwrap();
|
||||
let b = generate_refresh_token(1, TEST_SECRET).unwrap();
|
||||
assert_ne!(a, b, "两次生成的 refresh token 不应相同");
|
||||
// UUID v4 格式:8-4-4-4-12 十六进制
|
||||
let parts: Vec<&str> = a.split('-').collect();
|
||||
assert_eq!(parts.len(), 5);
|
||||
assert!(parts.iter().all(|p| !p.is_empty()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_temp_token_roundtrip_and_expiry_window() {
|
||||
let token = generate_temp_token("openid_share", 777, TEST_SECRET, 10).unwrap();
|
||||
let claims = verify_temp_token(&token, TEST_SECRET).unwrap();
|
||||
assert_eq!(claims.openid, "openid_share");
|
||||
assert_eq!(claims.resource_id, 777);
|
||||
|
||||
// 10 分钟有效期:exp - iat 约等于 600 秒(允许 ±2 秒误差)
|
||||
let lifetime = claims.exp - claims.iat;
|
||||
assert!((598..=602).contains(&lifetime), "临时 token 有效期应为 10 分钟,实际 {lifetime}s");
|
||||
|
||||
assert!(verify_temp_token(&token, "wrong-secret").is_err());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user