This commit is contained in:
Mateusz Gruszczyński committed 2026-10-17 11:57:16 +02:00
1 parent 6b937aaf85
commit 87c8393d86
79 files changed
+6727 -297

No files matched your search

+69 -37
View File
@@ -901,13 +901,19 @@ mod tests {
.oneshot(request(path).body(Body::empty()).unwrap())
.await
.unwrap();
assert_eq!(public.status(), StatusCode::OK, "anonymous {path}");
let public_body = axum::body::to_bytes(public.into_body(), 100_000)
.await
.unwrap();
assert!(std::str::from_utf8(&public_body)
.unwrap()
.contains(&format!("/assets/login_{}.js", super::asset_build_id())));
if path == "/logs" {
// The operational log route is private even on browser refresh.
assert_eq!(public.status(), StatusCode::UNAUTHORIZED);
assert_eq!(json_body(public).await, json!({"error":"auth.required"}));
} else {
assert_eq!(public.status(), StatusCode::OK, "anonymous {path}");
let public_body = axum::body::to_bytes(public.into_body(), 100_000)
.await
.unwrap();
assert!(std::str::from_utf8(&public_body)
.unwrap()
.contains(&format!("/assets/login_{}.js", super::asset_build_id())));
}
let private = router
.clone()
@@ -1314,6 +1320,13 @@ mod tests {
.unwrap();
assert_eq!(response.status(), StatusCode::FORBIDDEN);
// This fixture has no certificate directory. An out-of-scope credential
// must see only the grant error, never the storage availability error.
assert_eq!(
json_body(response).await,
json!({"error":"certificate_api.certificate_forbidden"})
);
let missing_key = router
.clone()
.oneshot(
@@ -1821,6 +1834,32 @@ mod tests {
"backend_table_sort":"requests",
"backend_table_descending":true
});
// Older clients may omit fields added since their preferences were
// saved. The API returns and stores the typed, defaulted document.
let normalized = serde_json::to_value(
serde_json::from_value::<AdminPreferences>(selected.clone()).unwrap(),
)
.unwrap();
for (field, value) in selected.as_object().unwrap() {
assert_eq!(&normalized[field], value, "selected field {field}");
}
assert_eq!(normalized["dashboard_widget_sizes"], Value::Null);
assert_eq!(normalized["file_log_sort"], "time");
assert_eq!(normalized["file_log_descending"], true);
assert_eq!(normalized["vhost_list_sort"], "id");
assert_eq!(normalized["docker_vhost_sort"], "service");
assert_eq!(normalized["stream_list_sort"], "name");
assert_eq!(normalized["redirect_list_sort"], "id");
assert_eq!(normalized["notfound_list_sort"], "id");
for field in [
"vhost_list_descending",
"docker_vhost_descending",
"stream_list_descending",
"redirect_list_descending",
"notfound_list_descending",
] {
assert_eq!(normalized[field], false, "default field {field}");
}
let response = router
.clone()
.oneshot(
@@ -1837,12 +1876,12 @@ mod tests {
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
assert_eq!(json_body(response).await, selected);
assert_eq!(json_body(response).await, normalized);
let saved: Value =
serde_json::from_str(&store.admin_preferences("owner").await.unwrap().unwrap())
.unwrap();
assert_eq!(saved, selected);
assert_eq!(saved, normalized);
// Preferences must also survive a subsequent authenticated read.
let persisted = router
.clone()
@@ -1854,35 +1893,22 @@ mod tests {
)
.await
.unwrap();
let mut upgraded = selected.clone();
for id in [
"stream_overview",
"stream_traffic",
"stream_sessions",
"stream_backend_health",
"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",
] {
let mut upgraded = normalized.clone();
for widget in DASHBOARD_WIDGETS.iter() {
let id = json!(widget.id);
if selected["dashboard_widgets"].as_array().unwrap().contains(&id) {
continue;
}
upgraded["dashboard_widgets"]
.as_array_mut()
.unwrap()
.push(json!(id));
upgraded["dashboard_hidden_widgets"]
.as_array_mut()
.unwrap()
.push(json!(id));
.push(id.clone());
if widget.default_hidden {
upgraded["dashboard_hidden_widgets"]
.as_array_mut()
.unwrap()
.push(id);
}
}
assert_eq!(json_body(persisted).await, upgraded);
// Wrong allowlist value is rejected even if the rest is valid.
@@ -2192,7 +2218,10 @@ mod tests {
.await
.unwrap();
assert_eq!(response.status(), StatusCode::UNAUTHORIZED, "{path}");
assert_eq!(response.headers()["cache-control"], "no-store");
assert_eq!(
response.headers()["cache-control"],
"private, no-store, no-cache, no-transform"
);
assert!(!response
.headers()
.contains_key("access-control-allow-origin"));
@@ -2294,7 +2323,10 @@ mod tests {
.unwrap();
assert_eq!(response.status(), StatusCode::OK, "{path}");
assert_eq!(response.headers()["x-frame-options"], "DENY");
assert_eq!(response.headers()["cache-control"], "no-store");
assert_eq!(
response.headers()["cache-control"],
"private, no-store, no-cache, no-transform"
);
}
let response = router
.clone()