lesavka/testing/tests/server_camera_contract.rs

114 lines
4.2 KiB
Rust
Raw Normal View History

//! Integration coverage for the server camera-selection contract.
//!
//! Scope: exercise environment-driven camera mode selection and stable enum
//! string mappings via the public camera module API.
//! Targets: `server/src/camera.rs`.
//! Why: camera policy decides the entire stream transport path, so these
//! behavior contracts belong in centralized testing.
use lesavka_server::camera::{
CameraCodec, CameraOutput, current_camera_config, update_camera_config,
};
use serial_test::serial;
use temp_env::with_var;
#[test]
fn camera_enum_strings_are_stable() {
assert_eq!(CameraOutput::Uvc.as_str(), "uvc");
assert_eq!(CameraOutput::Hdmi.as_str(), "hdmi");
assert_eq!(CameraCodec::Mjpeg.as_str(), "mjpeg");
assert_eq!(CameraCodec::H264.as_str(), "h264");
}
#[test]
#[serial]
fn camera_config_uses_interval_when_fps_is_unset_or_invalid() {
with_var("LESAVKA_CAM_OUTPUT", Some("uvc"), || {
with_var("LESAVKA_UVC_WIDTH", Some("640"), || {
with_var("LESAVKA_UVC_HEIGHT", Some("360"), || {
with_var("LESAVKA_UVC_FPS", None::<&str>, || {
with_var("LESAVKA_UVC_INTERVAL", Some("250000"), || {
let cfg = update_camera_config();
assert_eq!(cfg.output, CameraOutput::Uvc);
assert_eq!(cfg.codec, CameraCodec::Mjpeg);
assert_eq!(cfg.width, 640);
assert_eq!(cfg.height, 360);
assert_eq!(cfg.fps, 40);
});
});
with_var("LESAVKA_UVC_FPS", Some("not-a-number"), || {
with_var("LESAVKA_UVC_INTERVAL", Some("250000"), || {
let cfg = update_camera_config();
assert_eq!(cfg.output, CameraOutput::Uvc);
assert_eq!(cfg.codec, CameraCodec::Mjpeg);
assert_eq!(cfg.width, 640);
assert_eq!(cfg.height, 360);
assert_eq!(cfg.fps, 40);
});
});
});
});
});
}
#[test]
#[serial]
fn camera_config_zero_interval_falls_back_to_default_fps() {
with_var("LESAVKA_CAM_OUTPUT", Some("uvc"), || {
with_var("LESAVKA_UVC_WIDTH", Some("800"), || {
with_var("LESAVKA_UVC_HEIGHT", Some("600"), || {
with_var("LESAVKA_UVC_FPS", None::<&str>, || {
with_var("LESAVKA_UVC_INTERVAL", Some("0"), || {
let cfg = update_camera_config();
assert_eq!(cfg.output, CameraOutput::Uvc);
assert_eq!(cfg.codec, CameraCodec::Mjpeg);
assert_eq!(cfg.width, 800);
assert_eq!(cfg.height, 600);
assert_eq!(cfg.fps, 25);
});
});
});
});
});
}
#[test]
#[serial]
fn camera_config_forced_hdmi_tracks_cached_state() {
with_var("LESAVKA_CAM_OUTPUT", Some("hdmi"), || {
let cfg = update_camera_config();
assert_eq!(cfg.output, CameraOutput::Hdmi);
assert_eq!(cfg.codec, CameraCodec::H264);
assert_eq!(cfg.fps, 30);
assert!(matches!(
(cfg.width, cfg.height),
(1920, 1080) | (1280, 720)
));
let cached = current_camera_config();
assert_eq!(cached.output, CameraOutput::Hdmi);
assert_eq!(cached.codec, CameraCodec::H264);
assert_eq!(cached.fps, 30);
});
}
#[test]
#[serial]
fn camera_config_output_override_is_case_insensitive() {
with_var("LESAVKA_CAM_OUTPUT", Some(" UVC "), || {
with_var("LESAVKA_UVC_WIDTH", Some("1024"), || {
with_var("LESAVKA_UVC_HEIGHT", Some("576"), || {
with_var("LESAVKA_UVC_FPS", Some("12"), || {
let cfg = update_camera_config();
assert_eq!(cfg.output, CameraOutput::Uvc);
assert_eq!(cfg.codec, CameraCodec::Mjpeg);
assert_eq!(cfg.width, 1024);
assert_eq!(cfg.height, 576);
assert_eq!(cfg.fps, 12);
});
});
});
});
}