- Add invite code starts/expires fields across contracts, API, Spacetime bindings, and admin UI - Enforce pending/expired invite code redemption behavior and expose admin status - Add admin write-operation confirmation guard and documentation - Add invite code contract/runtime tests
38 lines
1.4 KiB
Rust
38 lines
1.4 KiB
Rust
use serde_json::json;
|
|
use shared_contracts::runtime::{
|
|
AdminUpsertProfileInviteCodeRequest, ProfileInviteCodeAdminResponse,
|
|
};
|
|
|
|
#[test]
|
|
fn admin_upsert_invite_code_request_accepts_optional_validity_window() {
|
|
let request: AdminUpsertProfileInviteCodeRequest = serde_json::from_value(json!({
|
|
"inviteCode": "SY00000001",
|
|
"metadata": { "note": "测试" },
|
|
"startsAt": "2026-05-04T00:00:00Z",
|
|
"expiresAt": null
|
|
}))
|
|
.expect("邀请码管理请求应接受 startsAt/expiresAt");
|
|
|
|
assert_eq!(request.starts_at.as_deref(), Some("2026-05-04T00:00:00Z"));
|
|
assert_eq!(request.expires_at, None);
|
|
}
|
|
|
|
#[test]
|
|
fn admin_invite_code_response_serializes_window_and_status_as_camel_case() {
|
|
let response = ProfileInviteCodeAdminResponse {
|
|
user_id: "user-1".to_string(),
|
|
invite_code: "SY00000001".to_string(),
|
|
metadata: json!({}),
|
|
starts_at: Some("2026-05-04T00:00:00Z".to_string()),
|
|
expires_at: None,
|
|
status: "active".to_string(),
|
|
created_at: "2026-05-04T00:00:00Z".to_string(),
|
|
updated_at: "2026-05-04T00:00:00Z".to_string(),
|
|
};
|
|
|
|
let value = serde_json::to_value(response).expect("邀请码管理响应应可序列化");
|
|
assert_eq!(value["startsAt"], json!("2026-05-04T00:00:00Z"));
|
|
assert_eq!(value["expiresAt"], json!(null));
|
|
assert_eq!(value["status"], json!("active"));
|
|
}
|