use crate::model::app::{load_app_from_yaml, App, AppContext};
use crate::model::app::{
save_active_layout_to_yaml, save_complete_state_to_yaml, save_muxbox_bounds_to_yaml,
save_muxbox_content_to_yaml, save_muxbox_scroll_to_yaml,
};
use crate::model::common::InputBounds;
use crate::model::layout::Layout;
use crate::model::muxbox::MuxBox;
use crate::{Config, Message};
use serde_yaml;
use std::fs;
use std::path::PathBuf;
use tempfile::NamedTempFile;
#[test]
fn test_active_layout_yaml_persistence() {
let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
let temp_path = temp_file.path();
let test_yaml = r#"
app:
layouts:
- id: 'layout1'
title: 'First Layout'
active: true
children:
- id: 'box1'
position:
x1: 0%
y1: 0%
x2: 50%
y2: 50%
- id: 'layout2'
title: 'Second Layout'
active: false
children:
- id: 'box2'
position:
x1: 0%
y1: 0%
x2: 100%
y2: 100%
"#;
fs::write(&temp_path, test_yaml).expect("Failed to write test YAML");
save_active_layout_to_yaml(temp_path.to_str().unwrap(), "layout2")
.expect("Failed to save active layout");
let updated_content = fs::read_to_string(&temp_path).expect("Failed to read updated YAML");
let yaml_value: serde_yaml::Value =
serde_yaml::from_str(&updated_content).expect("Failed to parse updated YAML");
if let Some(serde_yaml::Value::Mapping(app)) = yaml_value.get("app") {
if let Some(serde_yaml::Value::Sequence(layouts)) = app.get("layouts") {
for layout in layouts {
if let serde_yaml::Value::Mapping(layout_map) = layout {
if let Some(serde_yaml::Value::String(id)) = layout_map.get("id") {
if let Some(serde_yaml::Value::Bool(active)) = layout_map.get("active") {
if id == "layout2" {
assert!(*active, "Layout2 should be active");
} else if id == "layout1" {
assert!(!*active, "Layout1 should not be active");
}
}
}
}
}
}
}
}
#[test]
fn test_muxbox_bounds_yaml_persistence() {
let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
let temp_path = temp_file.path();
let test_yaml = r#"
app:
layouts:
- id: 'layout1'
children:
- id: 'test_box'
position:
x1: 0%
y1: 0%
x2: 50%
y2: 50%
"#;
fs::write(&temp_path, test_yaml).expect("Failed to write test YAML");
let new_bounds = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "60%".to_string(),
y2: "60%".to_string(),
};
save_muxbox_bounds_to_yaml(temp_path.to_str().unwrap(), "test_box", &new_bounds)
.expect("Failed to save muxbox bounds");
let updated_content = fs::read_to_string(&temp_path).expect("Failed to read updated YAML");
let yaml_value: serde_yaml::Value =
serde_yaml::from_str(&updated_content).expect("Failed to parse updated YAML");
let mut found_box = false;
if let Some(serde_yaml::Value::Mapping(app)) = yaml_value.get("app") {
if let Some(serde_yaml::Value::Sequence(layouts)) = app.get("layouts") {
for layout in layouts {
if let serde_yaml::Value::Mapping(layout_map) = layout {
if let Some(serde_yaml::Value::Sequence(children)) = layout_map.get("children")
{
for child in children {
if let serde_yaml::Value::Mapping(box_map) = child {
if let Some(serde_yaml::Value::String(id)) = box_map.get("id") {
if id == "test_box" {
found_box = true;
if let Some(serde_yaml::Value::Mapping(pos)) =
box_map.get("position")
{
assert_eq!(
pos.get("x1"),
Some(&serde_yaml::Value::String("10%".to_string()))
);
assert_eq!(
pos.get("y1"),
Some(&serde_yaml::Value::String("10%".to_string()))
);
assert_eq!(
pos.get("x2"),
Some(&serde_yaml::Value::String("60%".to_string()))
);
assert_eq!(
pos.get("y2"),
Some(&serde_yaml::Value::String("60%".to_string()))
);
}
}
}
}
}
}
}
}
}
}
assert!(found_box, "Test box should be found with updated bounds");
}
#[test]
fn test_muxbox_content_yaml_persistence() {
let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
let temp_path = temp_file.path();
let test_yaml = r#"
app:
layouts:
- id: 'layout1'
children:
- id: 'content_box'
content: 'Original content'
position:
x1: 0%
y1: 0%
x2: 50%
y2: 50%
"#;
fs::write(&temp_path, test_yaml).expect("Failed to write test YAML");
let new_content = "Updated content from live system";
save_muxbox_content_to_yaml(temp_path.to_str().unwrap(), "content_box", new_content)
.expect("Failed to save muxbox content");
let updated_content_str = fs::read_to_string(&temp_path).expect("Failed to read updated YAML");
let yaml_value: serde_yaml::Value =
serde_yaml::from_str(&updated_content_str).expect("Failed to parse updated YAML");
let mut found_content = false;
if let Some(serde_yaml::Value::Mapping(app)) = yaml_value.get("app") {
if let Some(serde_yaml::Value::Sequence(layouts)) = app.get("layouts") {
for layout in layouts {
if let serde_yaml::Value::Mapping(layout_map) = layout {
if let Some(serde_yaml::Value::Sequence(children)) = layout_map.get("children")
{
for child in children {
if let serde_yaml::Value::Mapping(box_map) = child {
if let Some(serde_yaml::Value::String(id)) = box_map.get("id") {
if id == "content_box" {
if let Some(serde_yaml::Value::String(content)) =
box_map.get("content")
{
assert_eq!(content, new_content);
found_content = true;
}
}
}
}
}
}
}
}
}
}
assert!(found_content, "Content should be found and updated");
}
#[test]
fn test_muxbox_scroll_yaml_persistence() {
let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
let temp_path = temp_file.path();
let test_yaml = r#"
app:
layouts:
- id: 'layout1'
children:
- id: 'scroll_box'
position:
x1: 0%
y1: 0%
x2: 50%
y2: 50%
"#;
fs::write(&temp_path, test_yaml).expect("Failed to write test YAML");
save_muxbox_scroll_to_yaml(temp_path.to_str().unwrap(), "scroll_box", 10, 5)
.expect("Failed to save muxbox scroll position");
let updated_content = fs::read_to_string(&temp_path).expect("Failed to read updated YAML");
let yaml_value: serde_yaml::Value =
serde_yaml::from_str(&updated_content).expect("Failed to parse updated YAML");
let mut found_scroll = false;
if let Some(serde_yaml::Value::Mapping(app)) = yaml_value.get("app") {
if let Some(serde_yaml::Value::Sequence(layouts)) = app.get("layouts") {
for layout in layouts {
if let serde_yaml::Value::Mapping(layout_map) = layout {
if let Some(serde_yaml::Value::Sequence(children)) = layout_map.get("children")
{
for child in children {
if let serde_yaml::Value::Mapping(box_map) = child {
if let Some(serde_yaml::Value::String(id)) = box_map.get("id") {
if id == "scroll_box" {
if let Some(serde_yaml::Value::Number(scroll_x)) =
box_map.get("scroll_x")
{
assert_eq!(scroll_x.as_u64(), Some(10));
}
if let Some(serde_yaml::Value::Number(scroll_y)) =
box_map.get("scroll_y")
{
assert_eq!(scroll_y.as_u64(), Some(5));
}
found_scroll = true;
}
}
}
}
}
}
}
}
}
assert!(found_scroll, "Scroll position should be found and updated");
}
#[test]
#[ignore]
fn test_complete_state_yaml_persistence() {
let mut app = App::new();
app.layouts.push(Layout {
id: "test_layout".to_string(),
title: Some("Test Layout".to_string()),
active: Some(true),
children: Some(vec![MuxBox {
id: "test_box".to_string(),
content: Some("Test content".to_string()),
position: InputBounds {
x1: "0%".to_string(),
y1: "0%".to_string(),
x2: "100%".to_string(),
y2: "100%".to_string(),
},
..Default::default()
}]),
..Default::default()
});
let config = Config::default();
let app_context = AppContext::new(app, config);
let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
let temp_path = temp_file.path();
save_complete_state_to_yaml(temp_path.to_str().unwrap(), &app_context)
.expect("Failed to save complete state");
let saved_content = fs::read_to_string(&temp_path).expect("Failed to read saved YAML");
println!("Saved YAML content: {}", saved_content);
let loaded_app_result = load_app_from_yaml(temp_path.to_str().unwrap());
if let Err(e) = &loaded_app_result {
println!("Error loading YAML: {}", e);
}
assert!(
loaded_app_result.is_ok(),
"Should be able to load saved state"
);
let loaded_app = loaded_app_result.unwrap();
assert_eq!(loaded_app.layouts.len(), 1);
assert_eq!(loaded_app.layouts[0].id, "test_layout");
assert_eq!(loaded_app.layouts[0].title, Some("Test Layout".to_string()));
assert_eq!(loaded_app.layouts[0].active, Some(true));
let children = loaded_app.layouts[0].children.as_ref().unwrap();
assert_eq!(children.len(), 1);
assert_eq!(children[0].id, "test_box");
assert_eq!(children[0].content, Some("Test content".to_string()));
}
#[test]
fn test_atomic_yaml_writes() {
let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
let temp_path = temp_file.path();
let test_yaml = r#"
app:
layouts:
- id: 'layout1'
children:
- id: 'test_box'
position:
x1: 0%
y1: 0%
x2: 50%
y2: 50%
"#;
fs::write(&temp_path, test_yaml).expect("Failed to write test YAML");
let temp_atomic_path = format!("{}.tmp", temp_path.to_str().unwrap());
let new_bounds = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "60%".to_string(),
y2: "60%".to_string(),
};
save_muxbox_bounds_to_yaml(temp_path.to_str().unwrap(), "test_box", &new_bounds)
.expect("Failed to save muxbox bounds");
assert!(
!PathBuf::from(&temp_atomic_path).exists(),
"Temporary file should be cleaned up after atomic write"
);
let updated_content = fs::read_to_string(&temp_path).expect("Failed to read updated YAML");
assert!(
updated_content.contains("x1: '10%'") || updated_content.contains("x1: 10%"),
"File should contain updated bounds"
);
}