Unlucky Launcher v0.0.1-alpha
CI / fmt (rustfmt --check) (push) Canceled after 0s
CI / clippy (ubuntu-latest) (push) Canceled after 0s
CI / clippy (windows-latest) (push) Canceled after 0s
CI / test (ubuntu-latest) (push) Canceled after 0s
CI / test (windows-latest) (push) Canceled after 0s
CI / build release (ubuntu-latest) (push) Canceled after 0s
CI / build release (windows-latest) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s

Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent),
MCP server 接入外部 Agent 工具,GUI 开发中。
This commit is contained in:
AskaEth committed 2026-10-31 21:54:10 +08:00
commit bc41dfcf7d
517 files changed
+92844

No files matched your search

+97
View File
@@ -0,0 +1,97 @@
//! authlib 轨的纯函数/模型测试(HTTP 部分在 `tests/auth/authlib_api.rs`)。
use super::{normalize_api_root, AuthlibEndpoints, AuthlibProfile, AuthlibSession, USER_TYPE_MSA};
use crate::auth::secret::Secret;
#[test]
fn api_root_normalization() {
assert_eq!(
normalize_api_root("littleskin.cn/api/yggdrasil").expect("补协议"),
"https://littleskin.cn/api/yggdrasil/"
);
assert_eq!(
normalize_api_root(" http://127.0.0.1:8080/api/yggdrasil/ ").expect("保留协议"),
"http://127.0.0.1:8080/api/yggdrasil/"
);
assert_eq!(
normalize_api_root("https://littleskin.cn").expect("根域名"),
"https://littleskin.cn/"
);
assert!(normalize_api_root(" ").is_err());
assert!(normalize_api_root("https://").is_err());
}
#[test]
fn endpoints_follow_directory_layout() {
let endpoints =
AuthlibEndpoints::from_api_root("https://example.invalid/api/yggdrasil").expect("端点");
assert_eq!(
endpoints.authenticate,
"https://example.invalid/api/yggdrasil/authserver/authenticate"
);
assert_eq!(
endpoints.refresh,
"https://example.invalid/api/yggdrasil/authserver/refresh"
);
assert_eq!(
endpoints.validate,
"https://example.invalid/api/yggdrasil/authserver/validate"
);
assert_eq!(
endpoints.invalidate,
"https://example.invalid/api/yggdrasil/authserver/invalidate"
);
}
#[test]
fn placeholders_require_a_profile() {
let without = AuthlibSession {
access_token: Secret::new("token"),
client_token: Secret::new("client"),
selected_profile: None,
};
assert!(!without.has_profile());
assert!(without.to_placeholders().is_err());
let with = AuthlibSession {
selected_profile: Some(AuthlibProfile {
id: "0123456789abcdef0123456789abcdef".to_string(),
name: "Steve".to_string(),
}),
..without
};
assert!(with.has_profile());
let placeholders = with.to_placeholders().expect("占位符");
assert_eq!(placeholders.player_name, "Steve");
assert_eq!(placeholders.uuid, "0123456789abcdef0123456789abcdef");
assert_eq!(placeholders.user_type, USER_TYPE_MSA);
assert_eq!(placeholders.access_token, "token");
}
#[test]
fn session_debug_never_leaks_tokens() {
let session = AuthlibSession {
access_token: Secret::new("access-token-value"),
client_token: Secret::new("client-token-value"),
selected_profile: None,
};
let debug = format!("{session:?}");
assert!(!debug.contains("access-token-value"));
assert!(!debug.contains("client-token-value"));
assert_eq!(session.secrets().len(), 2);
}
#[test]
fn session_survives_json_roundtrip() {
let session = AuthlibSession {
access_token: Secret::new("access-token-value"),
client_token: Secret::new("client-token-value"),
selected_profile: Some(AuthlibProfile {
id: "0123456789abcdef0123456789abcdef".to_string(),
name: "Steve".to_string(),
}),
};
let text = serde_json::to_string(&session).expect("序列化");
let back: AuthlibSession = serde_json::from_str(&text).expect("反序列化");
assert_eq!(back, session);
}