Files
RustProxy/src/admin/preferences_tests.rs
T
2026-10-20 11:19:55 +02:00

263 lines
8.8 KiB
Rust

#[test]
fn overview_factory_preset_matches_registry_and_operator_visibility() {
let order = default_admin_dashboard_widgets();
let hidden = default_hidden_dashboard_widgets();
let unique: std::collections::HashSet<&str> = order.iter().map(String::as_str).collect();
assert_eq!(unique.len(), order.len());
assert_eq!(order.len(), DASHBOARD_WIDGETS.len());
assert_eq!(order.first().map(String::as_str), Some("requests"));
assert_eq!(order, DASHBOARD_DEFAULT_PRESET.dashboard_widgets);
assert_eq!(hidden, DASHBOARD_DEFAULT_PRESET.dashboard_hidden_widgets);
assert_eq!(default_admin_dashboard_density(), "compact");
assert_eq!(DASHBOARD_DEFAULT_PRESET.overview_samples, 600);
for id in [
"backend_traffic",
"backend_latency",
"extra_response_latency",
"wide_transform_activity",
"wide_compression_activity",
"cache",
"backend_table",
] {
assert!(order.contains(&id.to_owned()), "not registered: {id}");
assert!(
!hidden.contains(&id.to_owned()),
"should start visible: {id}"
);
}
for id in [
"bandwidth",
"backend_health",
"extra_process_cpu",
"stream_traffic",
"wide_cache_activity",
"cache_outcomes",
"www_status",
"www_requests",
"www_top_services",
] {
assert!(hidden.contains(&id.to_owned()), "should start hidden: {id}");
}
assert!(hidden.iter().all(|id| order.contains(id)));
assert!(validate_admin_preferences(&AdminPreferences::default()).is_ok());
}
#[test]
fn interface_themes_include_optional_black_and_cream_without_changing_default() {
let mut preferences = AdminPreferences::default();
assert_eq!(preferences.theme, "dark");
for theme in ["dark", "ultra_dark", "light", "cream"] {
preferences.theme = theme.to_owned();
assert!(validate_admin_preferences(&preferences).is_ok(), "{theme}");
}
preferences.theme = "sepia".to_owned();
assert!(validate_admin_preferences(&preferences).is_err());
}
#[test]
fn corner_style_defaults_and_rejects_unknown_presets() {
let mut prefs = AdminPreferences::default();
assert_eq!(prefs.corner_style, "default");
for preset in ["default", "square", "subtle", "rounded", "extra"] {
prefs.corner_style = preset.to_string();
assert!(validate_admin_preferences(&prefs).is_ok(), "{preset}");
}
prefs.corner_style = "oversized".to_string();
assert!(validate_admin_preferences(&prefs).is_err());
let old_json = r#"{"theme":"ultra_dark"}"#;
let old: AdminPreferences = serde_json::from_str(old_json).unwrap();
assert_eq!(old.corner_style, "default");
assert!(validate_admin_preferences(&old).is_ok());
}
#[test]
fn old_widget_preferences_preserve_order_opt_in_and_survive_unknown_ids() {
let mut prefs = AdminPreferences::default();
prefs.dashboard_widgets = vec![
"errors".into(),
"from_future_release".into(),
"requests".into(),
"errors".into(),
];
prefs.dashboard_hidden_widgets = vec![
"errors".into(),
"from_future_release".into(),
"errors".into(),
];
reconcile_dashboard_widgets(&mut prefs);
assert_eq!(prefs.dashboard_widgets[0], "errors");
assert_eq!(prefs.dashboard_widgets[1], "requests");
assert!(!prefs
.dashboard_widgets
.contains(&"from_future_release".into()));
assert!(!prefs
.dashboard_hidden_widgets
.contains(&"from_future_release".into()));
assert_eq!(
prefs
.dashboard_hidden_widgets
.iter()
.filter(|id| *id == "errors")
.count(),
1
);
assert!(prefs
.dashboard_hidden_widgets
.contains(&"stream_overview".into()));
assert!(prefs
.dashboard_hidden_widgets
.contains(&"stream_backend_health".into()));
assert!(prefs
.dashboard_hidden_widgets
.contains(&"backend_health".into()));
assert!(prefs
.dashboard_hidden_widgets
.contains(&"backend_protocols".into()));
assert!(prefs
.dashboard_hidden_widgets
.contains(&"backend_requests".into()));
assert!(prefs
.dashboard_hidden_widgets
.contains(&"backend_capacity".into()));
assert!(prefs
.dashboard_hidden_widgets
.contains(&"extra_process_cpu".into()));
assert!(prefs.dashboard_widgets.contains(&"backend_table".into()));
// 0.33.0 WWW cards stay opt-in when upgrading an old saved custom layout.
for id in [
"www_status",
"www_kind",
"www_capacity",
"www_methods",
"www_error_rate",
"www_php_requests",
"www_requests",
"www_latency",
"www_failures",
"www_traffic",
"www_top_services",
"www_status_trend",
] {
assert!(prefs.dashboard_widgets.contains(&id.into()), "missing {id}");
assert!(
prefs.dashboard_hidden_widgets.contains(&id.into()),
"visible on upgrade: {id}"
);
}
assert!(!prefs
.dashboard_hidden_widgets
.contains(&"backend_table".into()));
for id in [
"backend_http5xx",
"backend_timeouts",
"backend_network",
"backend_retries",
"backend_queue",
"backend_rotations",
] {
assert!(prefs.dashboard_hidden_widgets.contains(&id.into()));
}
assert!(validate_admin_preferences(&prefs).is_ok());
}
#[test]
fn saved_dashboard_order_and_visibility_survive_new_factory_preset() {
let mut prefs: AdminPreferences = serde_json::from_str(
r#"{
"dashboard_density":"normal",
"dashboard_widgets":["errors","requests","backend_traffic"],
"dashboard_hidden_widgets":["backend_traffic"]
}"#,
)
.unwrap();
reconcile_dashboard_widgets(&mut prefs);
assert_eq!(prefs.dashboard_density, "normal");
assert_eq!(
&prefs.dashboard_widgets[..3],
&["errors", "requests", "backend_traffic"]
);
assert!(!prefs
.dashboard_hidden_widgets
.contains(&"errors".to_owned()));
assert!(!prefs
.dashboard_hidden_widgets
.contains(&"requests".to_owned()));
assert!(prefs
.dashboard_hidden_widgets
.contains(&"backend_traffic".to_owned()));
// WWW was absent from the saved document and is introduced only as opt-in.
assert!(prefs
.dashboard_hidden_widgets
.contains(&"www_status".to_owned()));
assert!(prefs
.dashboard_hidden_widgets
.contains(&"cache_outcomes".to_owned()));
assert!(validate_admin_preferences(&prefs).is_ok());
}
#[test]
fn explicit_visible_stream_opt_in_is_not_reset_when_normalizing_saved_order() {
let mut prefs = AdminPreferences::default();
prefs.dashboard_widgets = default_admin_dashboard_widgets();
prefs.dashboard_hidden_widgets.clear();
reconcile_dashboard_widgets(&mut prefs);
assert!(prefs.dashboard_hidden_widgets.is_empty());
assert!(prefs.dashboard_widgets.contains(&"cache_outcomes".into()));
assert_eq!(prefs.dashboard_widgets, default_admin_dashboard_widgets());
assert!(validate_admin_preferences(&prefs).is_ok());
}
#[test]
fn dashboard_width_preferences_preserve_legacy_and_allow_custom_grids() {
let old: AdminPreferences = serde_json::from_str(r#"{"theme":"dark"}"#).unwrap();
assert!(old.dashboard_widget_sizes.is_none());
let mut prefs = AdminPreferences::default();
prefs.dashboard_widget_sizes = Some(std::collections::BTreeMap::new());
assert!(validate_admin_preferences(&prefs).is_ok());
for (id, span) in [
("http_protocol", 4),
("http_protocol", 3),
("requests", 4),
("www_requests", 3),
("backend_table", 6),
] {
prefs
.dashboard_widget_sizes
.as_mut()
.unwrap()
.insert(id.into(), span);
}
assert!(validate_admin_preferences(&prefs).is_ok());
let saved = serde_json::to_string(&prefs).unwrap();
let restored: AdminPreferences = serde_json::from_str(&saved).unwrap();
assert_eq!(
restored.dashboard_widget_sizes,
prefs.dashboard_widget_sizes
);
prefs
.dashboard_widget_sizes
.as_mut()
.unwrap()
.insert("backend_table".into(), 2);
assert!(validate_admin_preferences(&prefs).is_err());
prefs
.dashboard_widget_sizes
.as_mut()
.unwrap()
.insert("backend_table".into(), 12);
prefs
.dashboard_widget_sizes
.as_mut()
.unwrap()
.insert("not_a_card".into(), 3);
assert!(validate_admin_preferences(&prefs).is_err());
reconcile_dashboard_widgets(&mut prefs);
assert!(!prefs
.dashboard_widget_sizes
.as_ref()
.unwrap()
.contains_key("not_a_card"));
assert!(validate_admin_preferences(&prefs).is_ok());
}