#[test] fn overview_registry_is_single_source_of_identifiers_and_visibility_defaults() { 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.first().map(String::as_str), Some("requests")); assert!(order.contains(&"http3".to_owned())); assert!(hidden.contains(&"stream_overview".to_owned())); assert!(hidden.contains(&"stream_backend_health".to_owned())); for id in [ "backend_health", "backend_activity", "backend_errors", "backend_latency", "backend_traffic", "backend_protocols", "backend_requests", "backend_capacity", "backend_http5xx", "backend_timeouts", "backend_network", "backend_retries", "backend_queue", "backend_rotations", ] { assert!(order.contains(&id.to_owned())); assert!(hidden.contains(&id.to_owned())); } for id in [ "extra_process_cpu", "extra_process_rss", "extra_process_fds", "extra_open_connections", "extra_websocket_active", "extra_tls_error_rate", "extra_request_error_rate", "extra_cache_hit_rate", "extra_cache_memory", "extra_h2_share", "extra_response_latency", "extra_backend_unhealthy", ] { assert!(order.contains(&id.to_owned())); assert!(hidden.contains(&id.to_owned())); } for id in [ "traffic_chart", "system_chart", "connection_chart", "cache_diagnostics", "process_diagnostics", "network_diagnostics", "backend_table", ] { assert!(order.contains(&id.to_owned())); assert!(!hidden.contains(&id.to_owned())); } assert!(!hidden.contains(&"requests".to_owned())); 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 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_eq!(prefs.dashboard_widgets, default_admin_dashboard_widgets()); assert!(validate_admin_preferences(&prefs).is_ok()); }