88 lines
2.8 KiB
Rust
88 lines
2.8 KiB
Rust
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn stream_layout_default_is_canonical() {
|
|
let layout = StreamLayout::default();
|
|
assert_eq!(layout.control, 0);
|
|
assert_eq!(layout.input, 1);
|
|
assert_eq!(layout.authority, 2);
|
|
assert_eq!(layout.chunk_lod0, 3);
|
|
assert_eq!(layout.chunk_lod1, 4);
|
|
assert_eq!(layout.chunk_lod2, 5);
|
|
assert_eq!(layout.chunk_lod3, 6);
|
|
assert_eq!(layout.chunk_lod4, 7);
|
|
assert_eq!(layout.asset, 8);
|
|
assert_eq!(layout.mod_data, 9);
|
|
}
|
|
|
|
fn roundtrip_test(msg: &ControlMessage) -> Result<(), postcard::Error> {
|
|
let bytes = postcard::to_stdvec(msg)?;
|
|
let decoded: ControlMessage = postcard::from_bytes(&bytes)?;
|
|
assert_eq!(msg, &decoded);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn roundtrip_client_hello() -> Result<(), postcard::Error> {
|
|
let msg = ControlMessage::ClientHello(ClientHello {
|
|
protocol_version: PROTOCOL_VERSION,
|
|
client_build: "synvael-client-0.1.0".to_string(),
|
|
player_identity: PlayerIdentity {
|
|
display_name: "Player1".to_string(),
|
|
},
|
|
installed_packs: vec![PackRef {
|
|
id: "core:base".to_string(),
|
|
version: "1.0.0".to_string(),
|
|
content_hash: [0; 32],
|
|
tier: PackTier::Data,
|
|
}],
|
|
requested_features: FeatureFlags(0),
|
|
});
|
|
roundtrip_test(&msg)
|
|
}
|
|
|
|
#[test]
|
|
fn roundtrip_handshake_ack() -> Result<(), postcard::Error> {
|
|
let msg = ControlMessage::HandshakeAck(HandshakeAck {
|
|
protocol_version: PROTOCOL_VERSION,
|
|
server_build: "synvael-server-0.1.0".to_string(),
|
|
world_packs: vec![],
|
|
missing_packs: vec![],
|
|
stream_layout: StreamLayout::default(),
|
|
tick_rate_hint: 20,
|
|
});
|
|
roundtrip_test(&msg)
|
|
}
|
|
|
|
#[test]
|
|
fn roundtrip_handshake_reject() -> Result<(), postcard::Error> {
|
|
let msg = ControlMessage::HandshakeReject(HandshakeReject {
|
|
reason: RejectReason::ProtocolMismatch,
|
|
detail: "Expected v1, got v2".to_string(),
|
|
upgrade_url: Some("https://synvael.example/download".to_string()),
|
|
});
|
|
roundtrip_test(&msg)
|
|
}
|
|
|
|
#[test]
|
|
fn pack_tier_match_rules() {
|
|
// Resource packs are client-side overlays: a mismatch is always tolerated.
|
|
assert!(!PackTier::Resource.requires_strict_match());
|
|
// Data packs affect authoritative content and must match exactly.
|
|
assert!(PackTier::Data.requires_strict_match());
|
|
// A client-only mod cannot desync server state, so a mismatch is tolerated.
|
|
assert!(!PackTier::Mod { client_only: true }.requires_strict_match());
|
|
// A server-affecting mod must match exactly.
|
|
assert!(PackTier::Mod { client_only: false }.requires_strict_match());
|
|
}
|
|
|
|
#[test]
|
|
fn roundtrip_disconnect() -> Result<(), postcard::Error> {
|
|
let msg = ControlMessage::Disconnect(Disconnect {
|
|
reason: "Server closing".to_string(),
|
|
});
|
|
roundtrip_test(&msg)
|
|
}
|