use std::net::{Ipv4Addr, SocketAddr};
use a7n_core::layout::Placement;
use tempfile::TempDir;
use super::*;
use crate::pin_store::Entry;
fn placed_daemon(target_y: i32) -> (Daemon, TempDir, [MachineId; 3]) {
let dir = tempfile::tempdir().unwrap();
let mut daemon = Daemon::load(dir.path(), SocketAddr::from((Ipv4Addr::LOCALHOST, 0))).unwrap();
let own = daemon.identity.machine_id;
let target = MachineId::try_from(&[42; MachineId::LEN][..]).unwrap();
let later = MachineId::try_from(&[43; MachineId::LEN][..]).unwrap();
for id in [target, later] {
daemon.pins.add(Entry {
machine_id: id,
pin: daemon.identity.pin,
name: "peer".into(),
spki_der: None,
hw_addr: Some([2; 6]),
screen_mm: None,
});
}
let placements = [(own, 0, 0), (target, 100, target_y), (later, 200, 0)]
.map(|(id, x, y)| Placement {
id,
x,
y,
width: 100,
height: 100,
blocked: 0,
})
.to_vec();
daemon.layout.state = daemon.layout.state.edit(placements, own).unwrap();
(daemon, dir, [own, target, later])
}
#[tokio::test]
async fn crossing_exit_unpaired_target_returns_no_crossing() {
for target_y in [0, 100] {
let (mut daemon, _dir, [_, target, _]) = placed_daemon(target_y);
daemon.unpair(target).unwrap();
let crossing = daemon.crossing_exit(
(0, 0, 100, 100),
&[(0, 0, 100, 100).into()],
(99, 98),
(100, 1),
(Edge::Right, 0.98),
);
assert!(crossing.is_none());
}
}
#[tokio::test]
async fn cross_edge_outside_left_point_reaches_paired_target() {
let (mut daemon, _dir, [own, target, _]) = placed_daemon(0);
let mut placements = daemon.layout.state.placements().to_vec();
placements[1].x = -100;
daemon.layout.state = daemon.layout.state.edit(placements, own).unwrap();
daemon.wol.sender = Box::new(|_| Ok(()));
let bounds = Bounds {
x: 0,
y: 0,
width: 100,
height: 100,
};
let dx = -i32::try_from(a7n_proto::limits::DEFAULT_RESISTANCE_PX).unwrap();
daemon
.cross_edge(bounds, &[bounds], (-3, 50), (dx, 0), false)
.await;
let pending = daemon.wol.pending.as_ref().unwrap();
assert_eq!(pending.peer, target);
assert!(daemon.input.edge_no_target.is_none());
}
#[tokio::test]
async fn crossing_push_notch_enabled_only_accepts_top_push_inside_span() {
let (mut daemon, _dir, _) = placed_daemon(0);
let bounds = (0, 0, 100, 100);
let monitors = [bounds.into()];
let (_, events) = tokio::sync::mpsc::channel(1);
let (control, _) = tokio::sync::mpsc::channel(1);
daemon.input.capture = Some(a7n_platform::input::Capture {
bounds: bounds.into(),
monitors: monitors.to_vec().into(),
notch: Some((40, 0, 20, 5).into()),
events,
control,
});
daemon.config.input.notch_crossing = true;
let outside = daemon.crossing_push(bounds, &monitors, (20, 0), (0, -1), false);
let inside = daemon.crossing_push(bounds, &monitors, (50, 0), (0, -1), false);
assert!(outside.is_none());
assert!(inside.is_some_and(|push| push.0 == Edge::Top));
}