feat(payments): 增加兑换码与支付适配框架 (#299)

* feat(payments): 增加兑换码与支付适配框架

* fix(ci): 对齐 Rust 1.95 lint 与格式要求

* fix(payments): harden redeem code wallet credits

---------

Co-authored-by: fawney19 <elky0401@gmail.com>
This commit is contained in:
Entropy.Xu
2026-04-17 10:07:52 +08:00
committed by GitHub
parent 54d77598ae
commit 6964729cb7
36 changed files with 5129 additions and 274 deletions

View File

@@ -136,3 +136,72 @@ fn classifies_admin_payments_callbacks_as_admin_proxy_route() {
);
assert!(!decision.is_execution_runtime_candidate());
}
#[test]
fn classifies_admin_payments_redeem_code_routes_as_admin_proxy_route() {
let headers = headers(&[]);
let list_batches_uri: Uri = "/api/admin/payments/redeem-codes/batches"
.parse()
.expect("uri should parse");
let list_batches = classify_control_route(&http::Method::GET, &list_batches_uri, &headers)
.expect("route should classify");
assert_eq!(
list_batches.route_family.as_deref(),
Some("payments_manage")
);
assert_eq!(
list_batches.route_kind.as_deref(),
Some("list_redeem_code_batches")
);
let create_batch_uri: Uri = "/api/admin/payments/redeem-codes/batches"
.parse()
.expect("uri should parse");
let create_batch = classify_control_route(&http::Method::POST, &create_batch_uri, &headers)
.expect("route should classify");
assert_eq!(
create_batch.route_family.as_deref(),
Some("payments_manage")
);
assert_eq!(
create_batch.route_kind.as_deref(),
Some("create_redeem_code_batch")
);
let list_codes_uri: Uri = "/api/admin/payments/redeem-codes/batches/batch-1/codes"
.parse()
.expect("uri should parse");
let list_codes = classify_control_route(&http::Method::GET, &list_codes_uri, &headers)
.expect("route should classify");
assert_eq!(list_codes.route_family.as_deref(), Some("payments_manage"));
assert_eq!(list_codes.route_kind.as_deref(), Some("list_redeem_codes"));
let disable_code_uri: Uri = "/api/admin/payments/redeem-codes/codes/code-1/disable"
.parse()
.expect("uri should parse");
let disable_code = classify_control_route(&http::Method::POST, &disable_code_uri, &headers)
.expect("route should classify");
assert_eq!(
disable_code.route_family.as_deref(),
Some("payments_manage")
);
assert_eq!(
disable_code.route_kind.as_deref(),
Some("disable_redeem_code")
);
let delete_batch_uri: Uri = "/api/admin/payments/redeem-codes/batches/batch-1/delete"
.parse()
.expect("uri should parse");
let delete_batch = classify_control_route(&http::Method::POST, &delete_batch_uri, &headers)
.expect("route should classify");
assert_eq!(
delete_batch.route_family.as_deref(),
Some("payments_manage")
);
assert_eq!(
delete_batch.route_kind.as_deref(),
Some("delete_redeem_code_batch")
);
}

View File

@@ -211,6 +211,22 @@ fn classifies_user_monitoring_audit_logs_as_public_support_route() {
assert!(!decision.is_execution_runtime_candidate());
}
#[test]
fn classifies_wallet_redeem_as_public_support_route() {
let headers = headers(&[("authorization", "Bearer sk-test")]);
let uri: Uri = "/api/wallet/redeem".parse().expect("uri should parse");
let decision =
classify_control_route(&http::Method::POST, &uri, &headers).expect("route should classify");
assert_eq!(decision.route_class.as_deref(), Some("public_support"));
assert_eq!(decision.route_family.as_deref(), Some("wallet"));
assert_eq!(decision.route_kind.as_deref(), Some("redeem"));
assert_eq!(
decision.auth_endpoint_signature.as_deref(),
Some("user:wallet")
);
}
#[test]
fn classifies_announcement_unread_count_as_public_support_route() {
let headers = headers(&[]);