fabro/lib/foundation/fabro-api/tests/server_settings_round_trip.rs
2026-07-23 17:59:34 -04:00

116 lines
3.5 KiB
Rust

use std::any::{TypeId, type_name};
use fabro_api::types::{
LogDestination as ApiLogDestination, ObjectStoreSettings as ApiObjectStoreSettings,
ServerNamespace as ApiServerNamespace,
ServerSandboxProviderSettings as ApiServerSandboxProviderSettings,
ServerSandboxProvidersSettings as ApiServerSandboxProvidersSettings,
ServerSandboxSettings as ApiServerSandboxSettings, ServerSettings as ApiServerSettings,
};
use fabro_config::ServerSettingsBuilder;
use fabro_types::ServerSettings;
use fabro_types::settings::ServerNamespace;
use fabro_types::settings::server::{
LogDestination, ObjectStoreSettings, ServerSandboxProviderSettings,
ServerSandboxProvidersSettings, ServerSandboxSettings,
};
#[test]
fn server_settings_family_reuses_domain_types() {
assert_same_type::<ApiServerSettings, ServerSettings>();
assert_same_type::<ApiServerNamespace, ServerNamespace>();
assert_same_type::<ApiObjectStoreSettings, ObjectStoreSettings>();
assert_same_type::<ApiLogDestination, LogDestination>();
assert_same_type::<ApiServerSandboxSettings, ServerSandboxSettings>();
assert_same_type::<ApiServerSandboxProvidersSettings, ServerSandboxProvidersSettings>();
assert_same_type::<ApiServerSandboxProviderSettings, ServerSandboxProviderSettings>();
}
#[test]
fn server_settings_json_matches_openapi_shape() {
let settings = ServerSettingsBuilder::from_toml(
r#"
_version = 1
[server.listen]
type = "tcp"
address = "127.0.0.1:32276"
[server.api]
url = "https://api.fabro.example.com"
[server.web]
enabled = true
url = "https://fabro.example.com"
[server.auth]
methods = ["dev-token", "github"]
[server.auth.github]
allowed_usernames = ["alice"]
[server.sandbox.providers.daytona]
enabled = false
[server.storage]
root = "/srv/fabro"
[server.logging]
destination = "stdout"
[server.integrations.github]
enabled = true
strategy = "app"
app_id = "12345"
client_id = "Iv1.abcdef"
slug = "fabro-dev"
[server.integrations.github.webhooks]
strategy = "tailscale_funnel"
"#,
)
.expect("settings should resolve");
let json = serde_json::to_value(&settings).expect("server settings should serialize");
assert_eq!(json["server"]["listen"]["type"], "tcp");
assert_eq!(json["server"]["listen"]["address"], "127.0.0.1:32276");
assert_eq!(json["server"]["storage"]["root"], "/srv/fabro");
assert_eq!(json["server"]["logging"]["destination"], "stdout");
assert_eq!(
json["server"]["sandbox"]["providers"]["local"]["enabled"],
true
);
assert_eq!(
json["server"]["sandbox"]["providers"]["docker"]["enabled"],
true
);
assert_eq!(
json["server"]["sandbox"]["providers"]["daytona"]["enabled"],
false
);
assert!(
json["server"].get("ip_allowlist").is_none(),
"server settings API should not expose removed IP allowlist settings"
);
assert!(
json["server"]["integrations"]["github"]["webhooks"]
.get("ip_allowlist")
.is_none(),
"github webhook settings API should not expose removed IP allowlist settings"
);
assert!(json.get("features").is_none());
let round_trip: ApiServerSettings =
serde_json::from_value(json).expect("server settings should deserialize");
assert_eq!(round_trip, settings);
}
fn assert_same_type<T: 'static, U: 'static>() {
assert_eq!(
TypeId::of::<T>(),
TypeId::of::<U>(),
"{} should be the same type as {}",
type_name::<T>(),
type_name::<U>()
);
}