use std::time::Duration;
use super::common::unique_pipe_name;
use super::test_desktop::{
DaemonGuard, TestDesktop, TestWindow, query_windows, start_test_daemon, unique_title,
};
fn find_window_by_title<'a>(
json: &'a serde_json::Value,
title: &str,
) -> Option<&'a serde_json::Value> {
json["windows"]
.as_array()
.and_then(|arr| arr.iter().find(|w| w["title"].as_str() == Some(title)))
}
#[test]
fn event_hooking_detects_new_windows() {
let td = TestDesktop::create().expect("test desktop");
let pipe = unique_pipe_name();
let mut _child = start_test_daemon(&pipe, &td.name).expect("start daemon");
let _guard = DaemonGuard::new(&pipe);
std::thread::sleep(Duration::from_millis(500));
let title1 = unique_title("Hook-A");
let title2 = unique_title("Hook-B");
let w1 = TestWindow::create(&title1).expect("create window 1");
let w2 = TestWindow::create(&title2).expect("create window 2");
std::thread::sleep(Duration::from_millis(1000));
let json = query_windows(&pipe).expect("query after create");
let windows = json["windows"].as_array().expect("windows array");
assert!(
find_window_by_title(&json, &title1).is_some(),
"window '{title1}' should be in registry. Windows: {:?}",
windows
.iter()
.filter_map(|w| w["title"].as_str())
.collect::<Vec<_>>()
);
assert!(
find_window_by_title(&json, &title2).is_some(),
"window '{title2}' should be in registry. Windows: {:?}",
windows
.iter()
.filter_map(|w| w["title"].as_str())
.collect::<Vec<_>>()
);
println!(
"✓ event_hooking_detects_new_windows: {} windows in registry",
windows.len()
);
drop(w1);
drop(w2);
drop(td);
}
#[test]
fn event_hooking_create_and_destroy() {
let td = TestDesktop::create().expect("test desktop");
let pipe = unique_pipe_name();
let mut _child = start_test_daemon(&pipe, &td.name).expect("start daemon");
let _guard = DaemonGuard::new(&pipe);
std::thread::sleep(Duration::from_millis(500));
let title1 = unique_title("CD-1");
let title2 = unique_title("CD-2");
let w1 = TestWindow::create(&title1).expect("create window 1");
let w2 = TestWindow::create(&title2).expect("create window 2");
std::thread::sleep(Duration::from_millis(1000));
let json = query_windows(&pipe).expect("query after create");
assert!(
find_window_by_title(&json, &title1).is_some(),
"window 1 should exist"
);
assert!(
find_window_by_title(&json, &title2).is_some(),
"window 2 should exist"
);
let count_after_create = json["windows"].as_array().unwrap().len();
drop(w2);
std::thread::sleep(Duration::from_millis(1000));
let json2 = query_windows(&pipe).expect("query after destroy");
assert!(
find_window_by_title(&json2, &title2).is_none(),
"destroyed window '{title2}' should be removed from registry"
);
assert!(
find_window_by_title(&json2, &title1).is_some(),
"surviving window '{title1}' should still be in registry"
);
let count_after_destroy = json2["windows"].as_array().unwrap().len();
assert!(
count_after_destroy < count_after_create,
"count should decrease after destroy ({count_after_destroy} >= {count_after_create})"
);
println!("✓ event_hooking_create_and_destroy: {count_after_create} -> {count_after_destroy}");
drop(w1);
drop(td);
}
#[test]
fn event_hooking_minimize_and_restore() {
let td = TestDesktop::create().expect("test desktop");
let pipe = unique_pipe_name();
let mut _child = start_test_daemon(&pipe, &td.name).expect("start daemon");
let _guard = DaemonGuard::new(&pipe);
std::thread::sleep(Duration::from_millis(500));
let title = unique_title("Min");
let w = TestWindow::create(&title).expect("create window");
std::thread::sleep(Duration::from_millis(1000));
let json = query_windows(&pipe).expect("query initial");
let initial = find_window_by_title(&json, &title);
assert!(initial.is_some(), "window '{title}' should be in registry");
println!("Initial state: {}", initial.unwrap()["state"]);
w.minimize();
std::thread::sleep(Duration::from_millis(1000));
let json_min = query_windows(&pipe).expect("query minimized");
let m = find_window_by_title(&json_min, &title)
.unwrap_or_else(|| panic!("window '{title}' should still be in registry after minimize"));
let state = m["state"].to_string();
println!("Minimized state: {state}");
assert!(
state.contains("Minimized"),
"state should be Minimized, got: {state}"
);
w.restore();
std::thread::sleep(Duration::from_millis(1000));
let json_rest = query_windows(&pipe).expect("query restored");
let r = find_window_by_title(&json_rest, &title)
.unwrap_or_else(|| panic!("window '{title}' should still be in registry after restore"));
let state = r["state"].to_string();
println!("Restored state: {state}");
assert!(
state.contains("Active"),
"state should be Active after restore, got: {state}"
);
drop(w);
drop(td);
}