use super::config::{Place, Seat};
use serde_json::{Value, json};
fn seat(place: &Value) -> anyhow::Result<Seat> {
let mut fields = json!({"harness":{"id":"codex","home":"/tmp","program":"/bin/true","args":[]},"issuer":"https://lys.example","store":"wards"});
for (key, value) in place.as_object().into_iter().flatten() {
fields[key] = value.clone();
}
serde_json::from_value(fields).map_err(anyhow::Error::from)
}
fn refusal(place: &Value) -> String {
seat(place)
.err()
.map_or_else(|| "accepted".to_owned(), |error| error.to_string())
}
#[test]
fn a_network_seat_names_the_door_origin_and_the_store_endpoint() -> anyhow::Result<()> {
let seat = seat(
&json!({"door_url":"https://door.example:8443","store_endpoint":{"endpoint":"store.example:7443","server_name":"store.example","max_page":64}}),
)?;
let Place::Network { door_url, store } = &seat.place else {
anyhow::bail!("a network seat was read as a local one");
};
assert_eq!(door_url.as_str(), "https://door.example:8443/");
assert_eq!(store.endpoint, "store.example:7443");
assert_eq!(store.server_name, "store.example");
assert_eq!(store.max_page.map(std::num::NonZeroU32::get), Some(64));
assert!(store.timeout_ms.is_none());
Ok(())
}
#[test]
fn a_local_seat_is_read_as_it_always_was() -> anyhow::Result<()> {
let seat = seat(&json!({"door_socket":"/tmp/a.sock","serve_config":"/tmp/s.json"}))?;
assert!(
matches!(&seat.place, Place::Local { door_socket, serve_config }
if door_socket.as_os_str() == "/tmp/a.sock" && serve_config.as_os_str() == "/tmp/s.json"),
"the local seat lost its socket or config"
);
Ok(())
}
#[test]
fn a_seat_naming_parts_of_both_places_or_a_wrong_part_is_refused_by_name() {
let store = json!({"endpoint":"store.example:7443","server_name":"store.example"});
for (place, code) in [
(
json!({"door_socket":"/tmp/a.sock","serve_config":"/tmp/s.json","door_url":"https://door.example"}),
"seat_place_mixed",
),
(
json!({"serve_config":"/tmp/s.json","store_endpoint":store}),
"seat_place_mixed",
),
(
json!({"door_url":"https://door.example"}),
"seat_place_incomplete",
),
(
json!({"door_socket":"/tmp/a.sock"}),
"seat_place_incomplete",
),
(json!({}), "seat_place_incomplete"),
(
json!({"door_socket":"a.sock","serve_config":"/tmp/s.json"}),
"seat_paths_must_be_absolute",
),
(
json!({"door_url":"http://door.example","store_endpoint":store}),
"seat_door_url_requires_https",
),
(
json!({"door_url":"https://door.example/assistant","store_endpoint":store}),
"seat_door_url_invalid",
),
(
json!({"door_url":"https://user@door.example","store_endpoint":store}),
"seat_door_url_invalid",
),
(
json!({"door_url":"door.example","store_endpoint":store}),
"seat_door_url_invalid",
),
(
json!({"door_url":"https://door.example","store_endpoint":{"endpoint":"store.example","server_name":"store.example"}}),
"seat_store_endpoint_invalid",
),
(
json!({"door_url":"https://door.example","store_endpoint":{"endpoint":"store.example:7443"}}),
"seat_store_endpoint_requires_server_name",
),
(
json!({"door_url":"https://door.example","store_endpoint":{"endpoint":"store.example:7443","server_name":"store example"}}),
"seat_store_server_name_invalid",
),
] {
let refused = refusal(&place);
assert!(refused.starts_with(code), "{place}: {refused}");
}
}