#![allow(clippy::expect_used, clippy::unwrap_used, clippy::panic, reason = "test harness")]
use std::{env, sync::Arc};
use voidcrawl_mcp::{
AppState, VoidCrawlServer,
sessions::SessionRegistry,
tools::network::{
self, ENABLE_ENV, NetworkCaptureArmArgs, NetworkPatternArg, SessionCookiesArgs,
},
};
fn server() -> VoidCrawlServer {
VoidCrawlServer::new(Arc::new(AppState::new(Arc::new(SessionRegistry::default()))))
}
fn gate_is_closed() -> bool {
env::var(ENABLE_ENV).is_err()
}
#[tokio::test]
async fn session_cookies_is_refused_when_the_gate_is_closed() {
if !gate_is_closed() {
return; }
let err = network::cookies(&server(), SessionCookiesArgs { session_id: "nope".into() })
.await
.expect_err("session_cookies must refuse without the operator opt-in");
let message = format!("{err:?}");
assert!(message.contains(ENABLE_ENV), "refusal should name the env var to set, got: {message}");
assert!(
!message.contains("no such session"),
"gate must be checked before the session lookup, got: {message}"
);
}
#[tokio::test]
async fn raw_headers_opt_in_is_refused_when_the_gate_is_closed() {
if !gate_is_closed() {
return; }
let args = NetworkCaptureArmArgs {
session_id: "nope".into(),
patterns: vec![NetworkPatternArg { name: "api".into(), url_glob: "**/api/**".into() }],
include_sensitive_headers: true,
..Default::default()
};
let err = network::arm(&server(), args)
.await
.expect_err("include_sensitive_headers must refuse without the operator opt-in");
let message = format!("{err:?}");
assert!(message.contains(ENABLE_ENV), "refusal should name the env var to set, got: {message}");
assert!(
!message.contains("no such session"),
"gate must be checked before the session lookup, got: {message}"
);
}
#[tokio::test]
async fn arming_without_raw_access_still_validates_its_patterns() {
let args = NetworkCaptureArmArgs { session_id: "nope".into(), ..Default::default() };
let err = network::arm(&server(), args).await.expect_err("empty patterns must be rejected");
let message = format!("{err:?}");
assert!(message.contains("pattern"), "expected a pattern-validation error, got: {message}");
assert!(!message.contains(ENABLE_ENV), "gate must not be implicated, got: {message}");
}
#[tokio::test]
async fn cookie_lease_rejects_a_non_absolute_replay_origin() {
let err = network::cookie_lease_open(
&server(),
network::CookieLeaseOpenArgs {
session_id: "nope".into(),
replay_origin: "api.example.com".into(),
},
)
.await
.expect_err("a bare host is not an origin");
let message = format!("{err:?}");
assert!(
!message.contains("no such session"),
"scope must be validated before the session lookup, got: {message}"
);
}
#[tokio::test]
async fn revoking_an_unknown_lease_is_idempotent_not_an_error() {
let sessions = Arc::new(SessionRegistry::default());
let srv = VoidCrawlServer::new(Arc::new(AppState::new(Arc::clone(&sessions))));
let err = network::cookie_lease_revoke(
&srv,
network::CookieLeaseRevokeArgs {
session_id: "nope".into(),
lease_id: "whatever".into(),
reason: Some("auth_failed".into()),
},
)
.await;
assert!(err.is_err(), "an unknown session is still an error");
}