use super::*;
use crate::monitor::DeviceIdentifier;
use tempfile::tempdir;
#[test]
fn test_config_serialization() {
let mapping = KeyboardMapping::new("Test Keyboard", DeviceIdentifier::usb(1234), "External");
let config = Config::new("Default", vec![mapping]);
let yaml = serde_yaml::to_string(&config).unwrap();
let deserialized: Config = serde_yaml::from_str(&yaml).unwrap();
assert_eq!(config, deserialized);
}
#[test]
fn test_config_with_multiple_keyboards() {
let usb_mapping =
KeyboardMapping::new("USB Keyboard", DeviceIdentifier::usb(1234), "USB Profile");
let bluetooth_mapping = KeyboardMapping::new(
"Bluetooth Keyboard",
DeviceIdentifier::bluetooth("Magic Keyboard"),
"Bluetooth Profile",
);
let config = Config::new(
"Default",
vec![usb_mapping.clone(), bluetooth_mapping.clone()],
);
let yaml = serde_yaml::to_string(&config).unwrap();
let deserialized: Config = serde_yaml::from_str(&yaml).unwrap();
assert_eq!(config.keyboards.len(), 2);
assert_eq!(deserialized.keyboards.len(), 2);
assert_eq!(config, deserialized);
}
#[test]
fn test_config_save_and_load() {
let dir = tempdir().unwrap();
let config_path = dir.path().join("config.yml");
let mapping =
KeyboardMapping::new("Test Keyboard", DeviceIdentifier::usb(5678), "Test Profile");
let config = Config::new("Test Default", vec![mapping]);
config.save_to_path(&config_path).unwrap();
let loaded_config = Config::load_from_path(&config_path).unwrap();
assert_eq!(config, loaded_config);
}
#[test]
fn test_config_from_cli_args() {
let config = Config::from_cli_args(
1111,
"CLI Profile".to_string(),
Some("CLI Default".to_string()),
);
assert_eq!(config.keyboards.len(), 1);
assert_eq!(config.keyboards[0].profile, "CLI Profile");
assert_eq!(config.default_profile, "CLI Default");
match &config.keyboards[0].device {
DeviceIdentifier::Usb { product_id } => assert_eq!(*product_id, 1111),
_ => panic!("Expected USB device identifier"),
}
}
#[test]
fn test_config_from_cli_args_with_default() {
let config = Config::from_cli_args(2222, "CLI Profile".to_string(), None);
assert_eq!(config.keyboards.len(), 1);
assert_eq!(config.keyboards[0].profile, "CLI Profile");
assert_eq!(config.default_profile, DEFAULT_PROFILE_NAME);
}
#[test]
fn test_legacy_config_compatibility() {
let dir = tempdir().unwrap();
let config_path = dir.path().join("config.yml");
let legacy_yaml = r#"
keyboard_id: 1234
product_profile: "External"
default_profile: "Default"
"#;
fs::write(&config_path, legacy_yaml).unwrap();
let config = Config::load_from_path(&config_path).unwrap();
assert_eq!(config.keyboards.len(), 1);
assert_eq!(config.default_profile, "Default");
assert_eq!(config.keyboards[0].profile, "External");
match &config.keyboards[0].device {
DeviceIdentifier::Usb { product_id } => assert_eq!(*product_id, 1234),
_ => panic!("Expected USB device identifier"),
}
}
#[test]
fn test_device_identifier_display() {
let usb = DeviceIdentifier::usb(1234);
let bt = DeviceIdentifier::bluetooth("Magic Keyboard");
assert!(usb.display_name().contains("1234"));
assert!(bt.display_name().contains("Magic Keyboard"));
}
#[test]
fn test_validate_empty_keyboards() {
let config = Config::new("Default", vec![]);
let warnings = config.validate();
assert!(warnings.iter().any(|w| w.contains("No keyboard mappings")));
}
#[test]
fn test_validate_duplicate_usb_mappings() {
let mapping1 = KeyboardMapping::new("KB1", DeviceIdentifier::usb(1234), "Profile1");
let mapping2 = KeyboardMapping::new("KB2", DeviceIdentifier::usb(1234), "Profile2");
let config = Config::new("Default", vec![mapping1, mapping2]);
let warnings = config.validate();
assert!(warnings.iter().any(|w| w.contains("Duplicate device")));
}
#[test]
fn test_validate_duplicate_bluetooth_mappings() {
let mapping1 = KeyboardMapping::new(
"KB1",
DeviceIdentifier::bluetooth("Magic Keyboard"),
"Profile1",
);
let mapping2 = KeyboardMapping::new(
"KB2",
DeviceIdentifier::bluetooth("MAGIC KEYBOARD"),
"Profile2",
);
let config = Config::new("Default", vec![mapping1, mapping2]);
let warnings = config.validate();
assert!(warnings.iter().any(|w| w.contains("Duplicate device")));
}
#[test]
fn test_validate_empty_profile_name() {
let mapping = KeyboardMapping::new("KB1", DeviceIdentifier::usb(1234), "");
let config = Config::new("Default", vec![mapping]);
let warnings = config.validate();
assert!(warnings.iter().any(|w| w.contains("empty profile name")));
}
#[test]
fn test_validate_empty_bluetooth_name() {
let mapping = KeyboardMapping::new("BT KB", DeviceIdentifier::bluetooth(""), "BT Profile");
let config = Config::new("Default", vec![mapping]);
let warnings = config.validate();
assert!(
warnings
.iter()
.any(|w| w.contains("empty Bluetooth device name"))
);
}
#[test]
fn test_validate_valid_config() {
let mapping1 = KeyboardMapping::new("USB KB", DeviceIdentifier::usb(1234), "USB Profile");
let mapping2 = KeyboardMapping::new(
"BT KB",
DeviceIdentifier::bluetooth("Magic Keyboard"),
"BT Profile",
);
let config = Config::new("Default", vec![mapping1, mapping2]);
let warnings = config.validate();
assert!(warnings.is_empty());
}
#[test]
fn test_keyboard_mapping_with_priority() {
let mapping = KeyboardMapping::with_priority(
"High Priority KB",
DeviceIdentifier::usb(1234),
"High Priority Profile",
100,
);
assert_eq!(mapping.priority, 100);
assert_eq!(mapping.name, "High Priority KB");
}
#[test]
fn test_keyboard_mapping_default_priority() {
let mapping = KeyboardMapping::new("KB", DeviceIdentifier::usb(1234), "Profile");
assert_eq!(mapping.priority, 0);
}
#[test]
fn test_config_with_priority_serialization() {
let mapping =
KeyboardMapping::with_priority("Priority KB", DeviceIdentifier::usb(1234), "Profile", 50);
let config = Config::new("Default", vec![mapping]);
let yaml = serde_yaml::to_string(&config).unwrap();
let deserialized: Config = serde_yaml::from_str(&yaml).unwrap();
assert_eq!(deserialized.keyboards[0].priority, 50);
}