#[path = "stub_node_api.rs"]
mod stub_node_api;
use blvm_node::module::api::hub::{AuditEntry, ModuleApiHub};
use blvm_node::module::ipc::protocol::{RequestMessage, RequestPayload, ResponsePayload};
use blvm_node::module::security::permissions::{Permission, PermissionSet};
use blvm_node::module::traits::ModuleError;
use blvm_protocol::{Hash, OutPoint};
use std::sync::Arc;
use stub_node_api::MockNodeAPI;
#[tokio::test]
async fn test_module_api_hub_new() {
let node_api = Arc::new(MockNodeAPI);
let hub = ModuleApiHub::new(node_api);
assert!(true);
}
#[tokio::test]
async fn test_module_api_hub_register_permissions() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadBlockchain);
hub.register_module_permissions("test-module".to_string(), permissions);
assert!(true);
}
#[tokio::test]
async fn test_module_api_hub_handle_handshake() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::Handshake,
payload: RequestPayload::Handshake {
module_id: "test-module".to_string(),
module_name: "Test Module".to_string(),
version: "1.0.0".to_string(),
},
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::HandshakeAck { node_version }) = response.payload {
assert!(!node_version.is_empty());
} else {
panic!("Expected HandshakeAck");
}
}
#[tokio::test]
async fn test_module_api_hub_handle_handshake_id_mismatch() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::Handshake,
payload: RequestPayload::Handshake {
module_id: "wrong-module".to_string(),
module_name: "Test Module".to_string(),
version: "1.0.0".to_string(),
},
};
let result = hub.handle_request("test-module", request).await;
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
ModuleError::OperationError(_)
));
}
#[tokio::test]
async fn test_module_api_hub_handle_get_chain_tip() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadChainState);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::GetChainTip,
payload: RequestPayload::GetChainTip,
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::Hash(hash)) = response.payload {
assert_eq!(hash.len(), 32); } else {
panic!("Expected Hash response");
}
}
#[tokio::test]
async fn test_module_api_hub_handle_get_block() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadBlockchain);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::GetBlock,
payload: RequestPayload::GetBlock {
hash: Hash::default(),
},
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::Block(block)) = response.payload {
assert!(block.is_some());
} else {
panic!("Expected Block response");
}
}
#[tokio::test]
async fn test_module_api_hub_handle_get_block_header() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadBlockchain);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::GetBlockHeader,
payload: RequestPayload::GetBlockHeader {
hash: Hash::default(),
},
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::BlockHeader(header)) = response.payload {
assert!(header.is_some());
} else {
panic!("Expected BlockHeader response");
}
}
#[tokio::test]
async fn test_module_api_hub_handle_get_transaction() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadBlockchain);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::GetTransaction,
payload: RequestPayload::GetTransaction {
hash: Hash::default(),
},
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::Transaction(tx)) = response.payload {
assert!(tx.is_some());
} else {
panic!("Expected Transaction response");
}
}
#[tokio::test]
async fn test_module_api_hub_handle_has_transaction() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadBlockchain);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::HasTransaction,
payload: RequestPayload::HasTransaction {
hash: Hash::default(),
},
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::Bool(exists)) = response.payload {
assert!(exists);
} else {
panic!("Expected Bool response");
}
}
#[tokio::test]
async fn test_module_api_hub_handle_get_block_height() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadChainState);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::GetBlockHeight,
payload: RequestPayload::GetBlockHeight,
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::U64(height)) = response.payload {
assert_eq!(height, 100);
} else {
panic!("Expected U64 response");
}
}
#[tokio::test]
async fn test_module_api_hub_handle_get_utxo() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadUTXO);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::GetUtxo,
payload: RequestPayload::GetUtxo {
outpoint: OutPoint {
hash: Hash::default(),
index: 0,
},
},
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::Utxo(utxo)) = response.payload {
assert!(utxo.is_some());
} else {
panic!("Expected Utxo response");
}
}
#[tokio::test]
async fn test_module_api_hub_handle_subscribe_events() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::SubscribeEvents);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::SubscribeEvents,
payload: RequestPayload::SubscribeEvents {
event_types: vec![blvm_node::module::traits::EventType::NewBlock],
},
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_ok(), "Request failed: {:?}", result);
let response = result.unwrap();
if let Some(ResponsePayload::SubscribeAck) = response.payload {
} else {
panic!("Expected SubscribeAck response");
}
}
#[tokio::test]
async fn test_module_api_hub_permission_denied() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let empty_permissions = PermissionSet::new();
hub.register_module_permissions("test-module".to_string(), empty_permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::GetChainTip,
payload: RequestPayload::GetChainTip,
};
let result = hub.handle_request("test-module", request).await;
if let Err(e) = &result {
eprintln!("Error: {:?}", e);
}
assert!(result.is_err(), "Expected permission denied error");
assert!(matches!(
result.unwrap_err(),
ModuleError::OperationError(_)
));
}
#[tokio::test]
async fn test_module_api_hub_audit_log() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadChainState);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
let request = RequestMessage {
correlation_id: 1,
request_type: MessageType::GetChainTip,
payload: RequestPayload::GetChainTip,
};
let _ = hub.handle_request("test-module", request).await;
let audit_log = hub.get_audit_log(10);
assert!(!audit_log.is_empty());
assert_eq!(audit_log[0].module_id, "test-module");
assert_eq!(audit_log[0].api_call, "get_chain_tip");
assert!(audit_log[0].success);
}
#[tokio::test]
async fn test_module_api_hub_audit_log_limit() {
let node_api = Arc::new(MockNodeAPI);
let mut hub = ModuleApiHub::new(node_api);
let mut permissions = PermissionSet::new();
permissions.add(Permission::ReadBlockchain);
hub.register_module_permissions("test-module".to_string(), permissions);
use blvm_node::module::ipc::protocol::MessageType;
for i in 0..1500 {
let request = RequestMessage {
correlation_id: i,
request_type: MessageType::GetChainTip,
payload: RequestPayload::GetChainTip,
};
let _ = hub.handle_request("test-module", request).await;
}
let audit_log = hub.get_audit_log(2000);
assert!(audit_log.len() <= 1000); }