use plana::jsonrpc::MessageKind;
use plana::namespace;
use strum::{Display, EnumIter, EnumString};
namespace!(
"Surface",
Surface,
SurfaceMethod,
Ping as SyncReq => Pong,
Pong as OneWay,
);
fn resolves<T>() {}
#[test]
fn merged_http_module_carries_generic_descriptors() {
resolves::<plana::http::HealthResponse>();
resolves::<plana::http::NetworkInfo>();
resolves::<plana::http::BackendKind>();
resolves::<plana::http::ServiceStatus>();
}
#[test]
fn registration_state_reaches_consumers_at_the_crate_root() {
resolves::<plana::protocol_core::RegistrationState>();
resolves::<plana::RegistrationState>();
let unregistered = plana::RegistrationState::unregistered("surface-probe");
assert!(!unregistered.registered);
}
#[test]
fn merged_enums_module_carries_connection_topology() {
resolves::<plana::enums::ConnectionType>();
}
#[test]
fn jsonrpc_surface_resolves() {
resolves::<plana::jsonrpc::RpcMethodMap>();
resolves::<plana::jsonrpc::Method>();
resolves::<plana::jsonrpc::MessageKind>();
resolves::<plana::jsonrpc::JsonRpcRequest>();
resolves::<plana::jsonrpc::JsonRpcResponse>();
resolves::<plana::jsonrpc::JsonRpcError>();
}
#[test]
fn namespace_macro_is_invocable_from_an_external_crate() {
assert_eq!(SurfaceMethod::Ping.wire(), "Surface.Ping");
assert_eq!(SurfaceMethod::Pong.wire(), "Surface.Pong");
assert_eq!(SurfaceMethod::Ping.kind(), MessageKind::SyncReq);
assert_eq!(SurfaceMethod::Pong.kind(), MessageKind::OneWay);
assert!(!SurfaceMethod::Ping.is_one_way());
assert!(SurfaceMethod::Pong.is_one_way());
assert_eq!(SurfaceMethod::Ping.response(), Some(SurfaceMethod::Pong));
assert_eq!(SurfaceMethod::Pong.response(), None);
}
#[test]
fn rpc_method_map_registers_arbitrary_method_names() {
let methods = plana::jsonrpc::RpcMethodMap::empty().method(
"my.domain.op",
|params: serde_json::Value| async move {
Ok(serde_json::json!({ "echo": params["text"].clone() }))
},
);
let resp = futures::executor::block_on(
methods.dispatch(Some(serde_json::json!({ "text": "hi" })), "my.domain.op"),
);
assert_eq!(resp.result, Some(serde_json::json!({ "echo": "hi" })));
let missing = futures::executor::block_on(methods.dispatch(None, "nope"));
assert_eq!(missing.error.as_ref().map(|e| e.code), Some(-32601));
}
#[test]
fn rbac_module_resolves() {
resolves::<plana::rbac::Permission>();
resolves::<plana::rbac::PermissionScope>();
resolves::<plana::rbac::Role>();
let _ = plana::rbac::Permission::SystemAdmin.as_str();
}
#[cfg(feature = "tracing-helpers")]
#[test]
fn tracing_helpers_forwarded_through_umbrella() {
resolves::<plana::tracing_helpers::ShortTimer>();
let _ = plana::tracing_helpers::ShortTimer;
}
#[test]
fn protocol_module_resolves() {
resolves::<plana::jsonrpc::JsonRpcError>();
resolves::<plana::protocol::base_messages::BaseHeartbeatParams>();
resolves::<plana::protocol::handshake::HandshakeAckParams>();
}
#[test]
fn root_health_response_is_the_generic_one() {
resolves::<plana::HealthResponse>();
let _ = plana::HealthResponse::ok(
"1.0.0",
plana::http::BackendKind::Dev,
1,
plana::http::NetworkInfo::unknown(),
);
}
#[test]
fn root_handshake_primitives_resolve() {
resolves::<plana::HandshakeAckParams>();
let _ = plana::HANDSHAKE_VERSION;
}
#[test]
fn identity_machine_fingerprint_resolves() {
let _: fn() -> Option<String> = plana::identity::machine_fingerprint;
}
#[test]
fn jsonrpc_framing_surface_resolves() {
resolves::<plana::jsonrpc::Id>();
resolves::<plana::jsonrpc::JsonRpcNotification>();
let _ = plana::jsonrpc::JSONRPC_VERSION;
let _ = plana::jsonrpc::error_codes::PARSE_ERROR;
let _ = plana::jsonrpc::error_codes::INVALID_REQUEST;
let _ = plana::jsonrpc::error_codes::METHOD_NOT_FOUND;
let _ = plana::jsonrpc::error_codes::INVALID_PARAMS;
let _ = plana::jsonrpc::error_codes::INTERNAL_ERROR;
let _ = plana::jsonrpc::error_codes::AUTH_ERROR;
assert_eq!(plana::jsonrpc::error_codes::AUTH_ERROR, -32005);
assert_eq!(plana::jsonrpc::error_codes::SNAPSHOT_FAILED, -32001);
}
#[test]
fn jsonrpc_session_surface_resolves() {
resolves::<plana::jsonrpc::session::SessionManager>();
let _ = plana::jsonrpc::session::sse_events_handler_impl;
}
#[test]
fn jsonrpc_method_sync_constructs_via_inner_and_flat_alias() {
let m = plana::jsonrpc::Method::Sync(plana::jsonrpc::pending::SyncMethod::Ping);
assert_eq!(m.method_name(), "Sync.Ping");
let flat = plana::jsonrpc::Method::SyncPing;
assert_eq!(flat.method_name(), "Sync.Ping");
assert_eq!(m.kind(), plana::jsonrpc::MessageKind::SyncReq);
}
#[test]
fn jsonrpc_flat_method_aliases_cover_the_consumer_namespaces() {
let agent_chunk_count = plana::jsonrpc::Method::SyncAgentChunkCount;
assert_eq!(agent_chunk_count.method_name(), "Sync.AgentChunkCount");
let base_heartbeat = plana::jsonrpc::Method::BaseHeartbeat;
assert_eq!(base_heartbeat.method_name(), "Base.Heartbeat");
let device_terminal_open = plana::jsonrpc::Method::DeviceTerminalOpen;
assert_eq!(device_terminal_open.method_name(), "Device.TerminalOpen");
let cli_status = plana::jsonrpc::Method::CliStatus;
assert_eq!(cli_status.method_name(), "Cli.Status");
let tool_list_tools = plana::jsonrpc::Method::ToolListTools;
assert_eq!(tool_list_tools.method_name(), "Tool.ListTools");
let skill_call = plana::jsonrpc::Method::SkillCallSkill;
assert_eq!(skill_call.method_name(), "Skill.CallSkill");
let skill_chain_start = plana::jsonrpc::Method::SyncSkillChainStart;
assert_eq!(skill_chain_start.method_name(), "Sync.SkillChainStart");
let screen_ice_candidate = plana::jsonrpc::Method::ScreenIceCandidate;
assert_eq!(screen_ice_candidate.method_name(), "Screen.IceCandidate");
let yolo_start = plana::jsonrpc::Method::SyncYoloStart;
assert_eq!(yolo_start.method_name(), "Sync.YoloStart");
assert_eq!(yolo_start.kind(), plana::jsonrpc::MessageKind::AsyncReq);
assert_eq!(
plana::jsonrpc::Method::Device(plana::jsonrpc::pending::DeviceMethod::TerminalOpen)
.method_name(),
device_terminal_open.method_name()
);
}
#[cfg(feature = "rpc-server")]
#[test]
fn rpc_server_module_surface_resolves() {
let _ = plana::rpc_server::detect_network;
let _ = plana::rpc_server::sse::SSE_HEARTBEAT_INTERVAL_SECS;
let _ = plana::rpc_server::sse::SSE_CONNECTED_COMMENT;
let _ = plana::rpc_server::sse::SSE_HEARTBEAT_COMMENT;
}