#![cfg(feature = "mock-server")]
use oxvif::mock::MockServer;
use oxvif::{ImagingSettings, OnvifSession};
async fn setup() -> (MockServer, OnvifSession) {
let server = MockServer::start().await.expect("start mock server");
let session = OnvifSession::builder(server.device_url())
.build()
.await
.expect("build session"); (server, session)
}
#[tokio::test]
async fn device_commands() {
let (_srv, s) = setup().await;
assert!(s.capabilities().media.url.is_some());
let info = s.get_device_info().await.unwrap();
assert_eq!(info.manufacturer, "oxvif-mock");
s.get_system_date_and_time().await.unwrap();
assert!(!s.get_scopes().await.unwrap().is_empty());
assert!(!s.get_users().await.unwrap().is_empty());
s.set_hostname("integration-cam").await.unwrap();
assert_eq!(
s.get_hostname().await.unwrap().name.as_deref(),
Some("integration-cam")
);
}
#[tokio::test]
async fn media_and_streaming() {
let (_srv, s) = setup().await;
let profiles = s.get_profiles().await.unwrap();
assert!(!profiles.is_empty());
let token = &profiles[0].token;
assert!(
s.get_stream_uri(token)
.await
.unwrap()
.uri
.starts_with("rtsp://")
);
assert!(!s.get_snapshot_uri(token).await.unwrap().uri.is_empty());
assert!(
!s.get_video_encoder_configurations()
.await
.unwrap()
.is_empty()
);
assert!(!s.get_osds(None).await.unwrap().is_empty());
}
#[tokio::test]
async fn media2_encoder_set_then_get() {
let (_srv, s) = setup().await;
assert!(!s.get_profiles_media2().await.unwrap().is_empty());
let mut cfg = s
.get_video_encoder_configurations_media2()
.await
.unwrap()
.remove(0);
if let Some(rc) = cfg.rate_control.as_mut() {
rc.bitrate_limit = 1234;
}
s.set_video_encoder_configuration_media2(&cfg)
.await
.unwrap();
let after = s.get_video_encoder_configurations_media2().await.unwrap();
assert_eq!(after[0].rate_control.as_ref().unwrap().bitrate_limit, 1234);
}
#[tokio::test]
async fn ptz_commands() {
let (_srv, s) = setup().await;
let profile = s.get_profiles().await.unwrap()[0].token.clone();
assert!(!s.ptz_get_nodes().await.unwrap().is_empty());
assert!(!s.ptz_get_presets(&profile).await.unwrap().is_empty());
s.ptz_absolute_move(&profile, 0.5, -0.3, 0.7).await.unwrap();
let status = s.ptz_get_status(&profile).await.unwrap();
assert_eq!(status.pan, Some(0.5));
assert_eq!(status.tilt, Some(-0.3));
}
#[tokio::test]
async fn imaging_set_then_get() {
let (_srv, s) = setup().await;
let vsc = "VideoSource_1";
let mut settings: ImagingSettings = s.get_imaging_settings(vsc).await.unwrap();
settings.brightness = Some(33.0);
s.set_imaging_settings(vsc, &settings).await.unwrap();
let after = s.get_imaging_settings(vsc).await.unwrap();
assert_eq!(after.brightness, Some(33.0));
}
#[tokio::test]
async fn events_pull_point() {
let (_srv, s) = setup().await;
let sub = s
.create_pull_point_subscription(None, Some("PT60S"))
.await
.unwrap();
let msgs = s
.pull_messages(&sub.reference_url, "PT1S", 10)
.await
.unwrap();
assert!(!msgs.is_empty(), "mock emits an event per pull");
}
#[tokio::test]
async fn recording_search_replay() {
let (_srv, s) = setup().await;
let _ = s.get_recordings().await.unwrap();
let token = s.find_recordings(None, "PT60S").await.unwrap();
assert!(!token.is_empty());
let uri = s
.get_replay_uri("rec1", "RTP-Unicast", "RTSP")
.await
.unwrap();
assert!(uri.starts_with("rtsp://"));
}
#[tokio::test]
async fn injected_fault_propagates() {
use oxvif::OnvifError;
use oxvif::soap::SoapError;
let server = MockServer::start().await.unwrap();
let s = OnvifSession::builder(server.device_url())
.build()
.await
.unwrap();
server.inject_fault("GetDeviceInformation", "ter:NotAuthorized", "denied");
let err = s.get_device_info().await.unwrap_err();
assert!(matches!(err, OnvifError::Soap(SoapError::Fault { .. })));
assert_eq!(
s.get_device_info().await.unwrap().manufacturer,
"oxvif-mock"
);
}