Merge pull request #9075 from TiggerTakkyTTT/test/server-api-moderation-goldens

🤖 Agent: Test-only: pins the moderation replies' status codes and bodies with independent literals. Union build passed.
This commit is contained in:
Ludovic Marie authored and GitHub committed 2026-11-05 04:50:53 +01:00
commit f5565f1a3c
2 files changed
+234

No files matched your search

+112
View File
@@ -546,6 +546,118 @@ mod tests {
std::fs::remove_dir_all(&dir).unwrap();
}
fn moderation_reply(response: Response) -> Value {
assert!(response.stream.is_none());
json!({
"status": response.status,
"content_type": response.content_type,
"headers": response.headers,
"body": serde_json::from_str::<Value>(&response.body).unwrap(),
})
}
#[test]
fn moderation_replies_match_api_v1_goldens() {
let golden: Value =
serde_json::from_str(include_str!("../testdata/api-v1-moderation.json")).unwrap();
let dir = std::env::temp_dir().join(format!(
"horizon-server-api-moderation-goldens-{}",
std::process::id()
));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
std::fs::write(dir.join(crate::config::FILE), crate::config::TEMPLATE).unwrap();
crate::config::update(&dir, "server", "online_mode", toml::Value::Boolean(false)).unwrap();
crate::config::update(&dir, "server", "whitelist", toml::Value::Boolean(false)).unwrap();
let shared = Shared::with_install(&dir, None);
shared.set_phase(Phase::Stopped);
let call = |path: &str, body: &[u8]| {
moderation_reply(crate::api::route(
&shared,
&crate::http::Request {
method: "POST".into(),
path: path.into(),
query: String::new(),
headers: Vec::new(),
body: body.to_vec(),
},
))
};
let check = |case: &str, path: &str, body: &[u8]| {
assert_eq!(call(path, body), golden[case], "{case}");
};
check("op", "/api/v1/players/op", br#"{"name":"Alex"}"#);
check("op_again", "/api/v1/players/op", br#"{"name":"Alex"}"#);
check("deop", "/api/v1/players/deop", br#"{"name":"Alex"}"#);
check("deop_again", "/api/v1/players/deop", br#"{"name":"Alex"}"#);
check(
"whitelist_add",
"/api/v1/whitelist/add",
br#"{"name":"Alex"}"#,
);
check(
"whitelist_add_again",
"/api/v1/whitelist/add",
br#"{"name":"Alex"}"#,
);
check("whitelist_on", "/api/v1/whitelist", br#"{"enabled":true}"#);
check(
"whitelist_on_again",
"/api/v1/whitelist",
br#"{"enabled":true}"#,
);
check(
"whitelist_remove",
"/api/v1/whitelist/remove",
br#"{"name":"Alex"}"#,
);
check(
"whitelist_remove_again",
"/api/v1/whitelist/remove",
br#"{"name":"Alex"}"#,
);
for (case, path, body) in [
(
"kick_stopped",
"/api/v1/players/kick",
br#"{"name":"Alex"}"#.as_slice(),
),
(
"ban_stopped",
"/api/v1/players/ban",
br#"{"name":"Alex"}"#.as_slice(),
),
(
"pardon_stopped",
"/api/v1/players/pardon",
br#"{"name":"Alex"}"#.as_slice(),
),
(
"ban_ip_stopped",
"/api/v1/players/ban-ip",
br#"{"ip":"203.0.113.7"}"#.as_slice(),
),
(
"pardon_ip_stopped",
"/api/v1/players/pardon-ip",
br#"{"ip":"203.0.113.7"}"#.as_slice(),
),
] {
check(case, path, body);
}
check("malformed", "/api/v1/players/op", b"not json");
check("bad_name", "/api/v1/players/op", br#"{"name":"a b"}"#);
check(
"bad_reason",
"/api/v1/players/kick",
br#"{"name":"Alex","reason":"first\nsecond"}"#,
);
check("bad_ip", "/api/v1/players/pardon-ip", br#"{"ip":"Alex"}"#);
check("bad_whitelist", "/api/v1/whitelist", br#"{}"#);
std::fs::remove_dir_all(&dir).unwrap();
}
#[test]
fn mods_come_from_the_build_record() {
let none = built_with(None);
+122
View File
@@ -0,0 +1,122 @@
{
"op": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": true, "output": ["Made Alex a server operator"]}
},
"op_again": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": false, "output": ["Nothing changed. The player already is an operator"]}
},
"deop": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": true, "output": ["Made Alex no longer a server operator"]}
},
"deop_again": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": false, "output": ["Nothing changed. The player is not an operator"]}
},
"whitelist_add": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": true, "output": ["Added Alex to the whitelist"]}
},
"whitelist_add_again": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": false, "output": ["Player is already whitelisted"]}
},
"whitelist_on": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": true, "output": ["Whitelist is now turned on"]}
},
"whitelist_on_again": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": false, "output": ["Whitelist is already turned on"]}
},
"whitelist_remove": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": true, "output": ["Removed Alex from the whitelist"]}
},
"whitelist_remove_again": {
"status": 200,
"content_type": "application/json",
"headers": [],
"body": {"changed": false, "output": ["Player is not whitelisted"]}
},
"kick_stopped": {
"status": 409,
"content_type": "application/json",
"headers": [],
"body": {"error": "the game isn't running right now"}
},
"ban_stopped": {
"status": 409,
"content_type": "application/json",
"headers": [],
"body": {"error": "the game isn't running right now"}
},
"pardon_stopped": {
"status": 409,
"content_type": "application/json",
"headers": [],
"body": {"error": "the game isn't running right now"}
},
"ban_ip_stopped": {
"status": 409,
"content_type": "application/json",
"headers": [],
"body": {"error": "the game isn't running right now"}
},
"pardon_ip_stopped": {
"status": 409,
"content_type": "application/json",
"headers": [],
"body": {"error": "the game isn't running right now"}
},
"malformed": {
"status": 400,
"content_type": "application/json",
"headers": [],
"body": {"error": "the body needs \"name\": a player's name (1 to 16 characters, no spaces)"}
},
"bad_name": {
"status": 400,
"content_type": "application/json",
"headers": [],
"body": {"error": "the body needs \"name\": a player's name (1 to 16 characters, no spaces)"}
},
"bad_reason": {
"status": 400,
"content_type": "application/json",
"headers": [],
"body": {"error": "\"reason\" is one line of at most 256 characters"}
},
"bad_ip": {
"status": 400,
"content_type": "application/json",
"headers": [],
"body": {"error": "the body needs \"ip\": an IPv4 or IPv6 address"}
},
"bad_whitelist": {
"status": 400,
"content_type": "application/json",
"headers": [],
"body": {"error": "the body needs \"enabled\": true or false"}
}
}