Skip to main content

a8e_test_support/
session.rs

1use std::sync::{Arc, Mutex};
2
3pub const TEST_SESSION_ID: &str = "test-session-id";
4pub const TEST_MODEL: &str = "gpt-5-nano";
5
6const NOT_YET_SET: &str = "session-id-not-yet-set";
7pub(crate) const SESSION_ID_HEADER: &str = "agent-session-id";
8
9#[derive(Clone)]
10pub struct ExpectedSessionId {
11    value: Arc<Mutex<String>>,
12    errors: Arc<Mutex<Vec<String>>>,
13}
14
15impl Default for ExpectedSessionId {
16    fn default() -> Self {
17        Self {
18            value: Arc::new(Mutex::new(NOT_YET_SET.to_string())),
19            errors: Arc::new(Mutex::new(Vec::new())),
20        }
21    }
22}
23
24impl ExpectedSessionId {
25    pub fn set(&self, id: impl Into<String>) {
26        *self.value.lock().unwrap() = id.into();
27    }
28
29    pub fn validate(&self, actual: Option<&str>) -> Result<(), String> {
30        let expected = self.value.lock().unwrap();
31        let err = match actual {
32            Some(act) if act == *expected => None,
33            _ => Some(format!(
34                "{} mismatch: expected '{}', got {:?}",
35                SESSION_ID_HEADER, expected, actual
36            )),
37        };
38        match err {
39            Some(e) => {
40                self.errors.lock().unwrap().push(e.clone());
41                Err(e)
42            }
43            None => Ok(()),
44        }
45    }
46
47    pub fn assert_matches(&self, actual: &str) {
48        let result = self.validate(Some(actual));
49        assert!(result.is_ok(), "{}", result.unwrap_err());
50        let errors = self.errors.lock().unwrap();
51        assert!(
52            errors.is_empty(),
53            "Session ID validation errors: {:?}",
54            *errors
55        );
56    }
57}