diff --git a/crates/miroir-core/src/scatter.rs b/crates/miroir-core/src/scatter.rs index 54f97b2..a1bdc91 100644 --- a/crates/miroir-core/src/scatter.rs +++ b/crates/miroir-core/src/scatter.rs @@ -79,3 +79,153 @@ impl Scatter for StubScatter { }) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::config::UnavailableShardPolicy; + + #[test] + fn test_scatter_request_creation() { + let request = ScatterRequest { + body: b"test body".to_vec(), + headers: vec![("Content-Type".to_string(), "application/json".to_string())], + method: "POST".to_string(), + path: "/search".to_string(), + }; + + assert_eq!(request.body, b"test body"); + assert_eq!(request.headers.len(), 1); + assert_eq!(request.method, "POST"); + assert_eq!(request.path, "/search"); + } + + #[test] + fn test_stub_scatter_returns_empty_response() { + let scatter = StubScatter; + let topology = Topology::new(1); + let nodes = vec![NodeId::new("node1".to_string())]; + let request = ScatterRequest { + body: Vec::new(), + headers: Vec::new(), + method: "GET".to_string(), + path: "/".to_string(), + }; + + let result = scatter + .scatter(&topology, nodes, request, UnavailableShardPolicy::Partial) + .unwrap(); + + assert!(result.responses.is_empty()); + assert!(result.failed.is_empty()); + } + + #[test] + fn test_scatter_response_empty() { + let response = ScatterResponse { + responses: Vec::new(), + failed: Vec::new(), + }; + + assert!(response.responses.is_empty()); + assert!(response.failed.is_empty()); + } + + #[test] + fn test_scatter_response_with_data() { + let node_response = NodeResponse { + node_id: NodeId::new("node1".to_string()), + body: b"response".to_vec(), + status: 200, + headers: vec![("Content-Type".to_string(), "application/json".to_string())], + }; + + let response = ScatterResponse { + responses: vec![node_response], + failed: vec![NodeId::new("node2".to_string())], + }; + + assert_eq!(response.responses.len(), 1); + assert_eq!(response.failed.len(), 1); + assert_eq!(response.responses[0].node_id.as_str(), "node1"); + assert_eq!(response.responses[0].status, 200); + assert_eq!(response.failed[0].as_str(), "node2"); + } + + #[test] + fn test_node_response_creation() { + let response = NodeResponse { + node_id: NodeId::new("test-node".to_string()), + body: b"test body".to_vec(), + status: 200, + headers: vec![("X-Custom".to_string(), "value".to_string())], + }; + + assert_eq!(response.node_id.as_str(), "test-node"); + assert_eq!(response.body, b"test body"); + assert_eq!(response.status, 200); + assert_eq!(response.headers.len(), 1); + assert_eq!(response.headers[0].0, "X-Custom"); + } + + #[test] + fn test_stub_scatter_with_empty_nodes() { + let scatter = StubScatter; + let topology = Topology::new(1); + let nodes: Vec = Vec::new(); + let request = ScatterRequest { + body: Vec::new(), + headers: Vec::new(), + method: "GET".to_string(), + path: "/".to_string(), + }; + + let result = scatter + .scatter(&topology, nodes, request, UnavailableShardPolicy::Partial) + .unwrap(); + + assert!(result.responses.is_empty()); + assert!(result.failed.is_empty()); + } + + #[test] + fn test_stub_scatter_with_multiple_nodes() { + let scatter = StubScatter; + let mut topology = Topology::new(1); + + let node1 = NodeId::new("node1".to_string()); + let node2 = NodeId::new("node2".to_string()); + let node3 = NodeId::new("node3".to_string()); + + topology.add_node(crate::topology::Node::new( + node1.clone(), + "http://node1".to_string(), + 0, + )); + topology.add_node(crate::topology::Node::new( + node2.clone(), + "http://node2".to_string(), + 0, + )); + topology.add_node(crate::topology::Node::new( + node3.clone(), + "http://node3".to_string(), + 0, + )); + + let nodes = vec![node1, node2, node3]; + let request = ScatterRequest { + body: Vec::new(), + headers: Vec::new(), + method: "POST".to_string(), + path: "/search".to_string(), + }; + + let result = scatter + .scatter(&topology, nodes, request, UnavailableShardPolicy::Partial) + .unwrap(); + + assert!(result.responses.is_empty()); + assert!(result.failed.is_empty()); + } +}