use super::*;
use crate::models::{Capability, CapabilityType};
#[test]
fn test_cell_add_remove_member() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
assert!(cell.add_member("node_1".to_string()));
assert!(cell.add_member("node_2".to_string()));
assert_eq!(cell.member_count(), 2);
assert!(!cell.add_member("node_1".to_string()));
assert_eq!(cell.member_count(), 2);
assert!(cell.remove_member("node_1"));
assert_eq!(cell.member_count(), 1);
assert!(!cell.remove_member("node_3"));
}
#[test]
fn test_cell_capacity() {
let config = CellConfig::new(2);
let mut cell = CellState::new(config);
assert!(cell.add_member("node_1".to_string()));
assert!(cell.add_member("node_2".to_string()));
assert!(cell.is_full());
assert!(!cell.add_member("node_3".to_string()));
}
#[test]
fn test_cell_leader_election() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
cell.add_member("node_1".to_string());
cell.add_member("node_2".to_string());
assert!(cell.set_leader("node_1".to_string()).is_ok());
assert_eq!(cell.leader_id, Some("node_1".to_string()));
assert!(cell.is_leader("node_1"));
assert!(!cell.is_leader("node_2"));
assert!(cell.set_leader("node_3".to_string()).is_err());
cell.clear_leader();
assert_eq!(cell.leader_id, None);
}
#[test]
fn test_cell_leader_removal() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
cell.add_member("node_1".to_string());
cell.set_leader("node_1".to_string()).unwrap();
cell.remove_member("node_1");
assert_eq!(cell.leader_id, None);
}
#[test]
fn test_cell_capabilities() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
let cap1 = Capability::new(
"camera_1".to_string(),
"HD Camera".to_string(),
CapabilityType::Sensor,
0.9,
);
let cap2 = Capability::new(
"gps_1".to_string(),
"GPS".to_string(),
CapabilityType::Sensor,
1.0,
);
let cap3 = Capability::new(
"compute_1".to_string(),
"Edge Compute".to_string(),
CapabilityType::Compute,
0.8,
);
cell.add_capability(cap1.clone());
cell.add_capability(cap2);
cell.add_capability(cap3);
assert_eq!(cell.capabilities.len(), 3);
cell.add_capability(cap1);
assert_eq!(cell.capabilities.len(), 3);
assert!(cell.has_capability_type(CapabilityType::Sensor));
assert!(cell.has_capability_type(CapabilityType::Compute));
assert!(!cell.has_capability_type(CapabilityType::Mobility));
let sensors = cell.get_capabilities_by_type(CapabilityType::Sensor);
assert_eq!(sensors.len(), 2);
}
#[test]
fn test_cell_cohort_assignment() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
assert_eq!(cell.cohort_id, None);
cell.assign_cohort("cohort_1".to_string());
assert_eq!(cell.cohort_id, Some("cohort_1".to_string()));
cell.leave_cohort();
assert_eq!(cell.cohort_id, None);
}
#[test]
fn test_cell_merge() {
let config = CellConfig::new(5);
let mut cell1 = CellState::new(config.clone());
let cell2 = CellState::new(config);
cell1.add_member("node_1".to_string());
cell1.add_member("node_2".to_string());
let mut cell2_temp = cell2.clone();
cell2_temp.add_member("node_2".to_string());
cell2_temp.add_member("node_3".to_string());
cell1.merge(&cell2_temp);
assert_eq!(cell1.member_count(), 3);
assert!(cell1.is_member("node_1"));
assert!(cell1.is_member("node_2"));
assert!(cell1.is_member("node_3"));
}
#[test]
fn test_cell_merge_leader() {
let config = CellConfig::new(5);
let mut cell1 = CellState::new(config.clone());
let mut cell2 = CellState::new(config);
cell1.add_member("node_1".to_string());
cell2.add_member("node_2".to_string());
cell1.set_leader("node_1".to_string()).unwrap();
std::thread::sleep(std::time::Duration::from_secs(1));
cell2.set_leader("node_2".to_string()).unwrap();
cell1.merge(&cell2);
assert_eq!(cell1.leader_id, Some("node_2".to_string()));
}
#[test]
fn test_cell_merge_capabilities() {
let config = CellConfig::new(5);
let mut cell1 = CellState::new(config.clone());
let mut cell2 = CellState::new(config);
let cap1 = Capability::new(
"camera".to_string(),
"Camera".to_string(),
CapabilityType::Sensor,
0.9,
);
let cap2 = Capability::new(
"gps".to_string(),
"GPS".to_string(),
CapabilityType::Sensor,
1.0,
);
cell1.add_capability(cap1);
cell2.add_capability(cap2);
cell1.merge(&cell2);
assert_eq!(cell1.capabilities.len(), 2);
}
#[test]
fn test_cell_is_valid() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
assert!(!cell.is_valid());
cell.add_member("node_1".to_string());
assert!(!cell.is_valid());
cell.add_member("node_2".to_string());
assert!(cell.is_valid());
}
#[test]
fn test_cell_config_with_id() {
let custom_id = "custom_cell_id".to_string();
let config = CellConfig::with_id(custom_id.clone(), 10);
assert_eq!(config.id, custom_id);
assert_eq!(config.max_size, 10);
assert_eq!(config.min_size, 2);
assert!(config.created_at.is_some());
}
#[test]
fn test_cell_config_new_generates_uuid() {
let config1 = CellConfig::new(5);
let config2 = CellConfig::new(5);
assert_ne!(config1.id, config2.id);
}
#[test]
fn test_cell_state_get_id() {
let config = CellConfig::with_id("test_id".to_string(), 5);
let cell = CellState::new(config);
assert_eq!(cell.get_id(), Some("test_id"));
}
#[test]
fn test_cell_state_get_id_no_config() {
let mut cell = CellState::new(CellConfig::new(5));
cell.config = None;
assert_eq!(cell.get_id(), None);
}
#[test]
fn test_cell_add_member_when_full() {
let config = CellConfig::new(2);
let mut cell = CellState::new(config);
assert!(cell.add_member("node_1".to_string()));
assert!(cell.add_member("node_2".to_string()));
assert!(cell.is_full());
assert!(!cell.add_member("node_3".to_string()));
assert_eq!(cell.member_count(), 2);
}
#[test]
fn test_cell_remove_non_existent_member() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
cell.add_member("node_1".to_string());
assert!(!cell.remove_member("node_2"));
assert!(!cell.remove_member(""));
assert_eq!(cell.member_count(), 1);
}
#[test]
fn test_cell_set_leader_not_member() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
cell.add_member("node_1".to_string());
let result = cell.set_leader("node_2".to_string());
assert!(result.is_err());
assert_eq!(result.unwrap_err(), "Leader must be a cell member");
}
#[test]
fn test_cell_clear_leader() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
cell.add_member("node_1".to_string());
cell.set_leader("node_1".to_string()).unwrap();
assert!(cell.is_leader("node_1"));
cell.clear_leader();
assert!(!cell.is_leader("node_1"));
assert_eq!(cell.leader_id, None);
}
#[test]
fn test_cell_is_member() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
cell.add_member("node_1".to_string());
cell.add_member("node_2".to_string());
assert!(cell.is_member("node_1"));
assert!(cell.is_member("node_2"));
assert!(!cell.is_member("node_3"));
assert!(!cell.is_member(""));
}
#[test]
fn test_cell_capabilities_duplicate_handling() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
let cap = Capability::new(
"cap_1".to_string(),
"Capability 1".to_string(),
CapabilityType::Sensor,
0.9,
);
cell.add_capability(cap.clone());
assert_eq!(cell.capabilities.len(), 1);
cell.add_capability(cap.clone());
assert_eq!(cell.capabilities.len(), 1);
let cap2 = Capability::new(
"cap_2".to_string(),
"Capability 2".to_string(),
CapabilityType::Sensor,
0.8,
);
cell.add_capability(cap2);
assert_eq!(cell.capabilities.len(), 2);
}
#[test]
fn test_cell_has_capability_type_empty() {
let config = CellConfig::new(5);
let cell = CellState::new(config);
assert!(!cell.has_capability_type(CapabilityType::Sensor));
assert!(!cell.has_capability_type(CapabilityType::Compute));
}
#[test]
fn test_cell_get_capabilities_by_type_empty() {
let config = CellConfig::new(5);
let cell = CellState::new(config);
let caps = cell.get_capabilities_by_type(CapabilityType::Sensor);
assert_eq!(caps.len(), 0);
}
#[test]
fn test_cell_merge_empty_cells() {
let config = CellConfig::new(5);
let mut cell1 = CellState::new(config.clone());
let cell2 = CellState::new(config);
cell1.merge(&cell2);
assert_eq!(cell1.member_count(), 0);
assert_eq!(cell1.capabilities.len(), 0);
}
#[test]
fn test_cell_merge_with_older_timestamp() {
let config = CellConfig::new(5);
let mut cell1 = CellState::new(config.clone());
let mut cell2 = CellState::new(config);
cell1.add_member("node_1".to_string());
std::thread::sleep(std::time::Duration::from_millis(10));
cell1.set_leader("node_1".to_string()).unwrap();
cell2.add_member("node_2".to_string());
cell1.merge(&cell2);
assert_eq!(cell1.leader_id, Some("node_1".to_string()));
assert_eq!(cell1.member_count(), 2);
}
#[test]
fn test_cell_cohort_assignment_multiple_times() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
cell.assign_cohort("cohort_1".to_string());
assert_eq!(cell.cohort_id, Some("cohort_1".to_string()));
cell.assign_cohort("cohort_2".to_string());
assert_eq!(cell.cohort_id, Some("cohort_2".to_string()));
cell.leave_cohort();
assert_eq!(cell.cohort_id, None);
}
#[test]
fn test_cell_is_full_no_config() {
let mut cell = CellState::new(CellConfig::new(5));
cell.config = None;
assert!(!cell.is_full());
}
#[test]
fn test_cell_is_valid_no_config() {
let mut cell = CellState::new(CellConfig::new(5));
cell.add_member("node_1".to_string());
cell.add_member("node_2".to_string());
cell.config = None;
assert!(!cell.is_valid());
}
#[test]
fn test_cell_update_timestamp() {
let config = CellConfig::new(5);
let mut cell = CellState::new(config);
let initial_ts = cell.timestamp.as_ref().map(|t| t.seconds).unwrap_or(0);
std::thread::sleep(std::time::Duration::from_millis(10));
cell.update_timestamp();
let new_ts = cell.timestamp.as_ref().map(|t| t.seconds).unwrap_or(0);
assert!(new_ts >= initial_ts);
}
#[test]
fn test_cell_config_default_min_size() {
let config = CellConfig::new(10);
assert_eq!(config.min_size, 2);
}
#[test]
fn test_cell_merge_capabilities_union() {
let config = CellConfig::new(5);
let mut cell1 = CellState::new(config.clone());
let mut cell2 = CellState::new(config);
let cap1 = Capability::new(
"cap_1".to_string(),
"Cap 1".to_string(),
CapabilityType::Sensor,
0.9,
);
let cap2 = Capability::new(
"cap_2".to_string(),
"Cap 2".to_string(),
CapabilityType::Compute,
0.8,
);
let cap3 = Capability::new(
"cap_3".to_string(),
"Cap 3".to_string(),
CapabilityType::Mobility,
0.7,
);
cell1.add_capability(cap1.clone());
cell1.add_capability(cap2.clone());
cell2.add_capability(cap2.clone()); cell2.add_capability(cap3);
cell1.merge(&cell2);
assert_eq!(cell1.capabilities.len(), 3);
}
#[test]
fn test_cell_merge_members_union() {
let config = CellConfig::new(10);
let mut cell1 = CellState::new(config.clone());
let mut cell2 = CellState::new(config);
cell1.add_member("node_1".to_string());
cell1.add_member("node_2".to_string());
cell2.add_member("node_2".to_string()); cell2.add_member("node_3".to_string());
cell2.add_member("node_4".to_string());
cell1.merge(&cell2);
assert_eq!(cell1.member_count(), 4);
assert!(cell1.is_member("node_1"));
assert!(cell1.is_member("node_2"));
assert!(cell1.is_member("node_3"));
assert!(cell1.is_member("node_4"));
}