Fix subnets validation
This commit is contained in:
+55
-17
@@ -19,7 +19,7 @@ use super::events::{
|
||||
};
|
||||
use super::forms::{FormAction, FormController};
|
||||
use super::render;
|
||||
use super::state::{Screen, UiState};
|
||||
use super::state::{Screen, SessionView, UiState};
|
||||
use crate::app::Application;
|
||||
|
||||
const MIN_WIDTH: u16 = 34;
|
||||
@@ -765,22 +765,7 @@ fn handle_key(
|
||||
state.screen = Screen::Message;
|
||||
return;
|
||||
};
|
||||
let mut issues = Vec::new();
|
||||
issues.extend(
|
||||
view.document_issues
|
||||
.iter()
|
||||
.map(|issue| format!("Document issue: {issue:?}")),
|
||||
);
|
||||
for client in &view.clients {
|
||||
for issue in &client.issues {
|
||||
issues.push(format!("Peer at line {}: {issue:?}", client.line));
|
||||
}
|
||||
}
|
||||
state.status_message = Some(if issues.is_empty() {
|
||||
"No document or peer issues were reported.".to_owned()
|
||||
} else {
|
||||
issues.join("\n")
|
||||
});
|
||||
state.status_message = Some(issue_summary(view));
|
||||
state.screen = Screen::Message;
|
||||
state.scroll_offset = 0;
|
||||
}
|
||||
@@ -802,6 +787,25 @@ fn handle_key(
|
||||
}
|
||||
}
|
||||
|
||||
fn issue_summary(view: &SessionView) -> String {
|
||||
let mut issues = Vec::new();
|
||||
issues.extend(
|
||||
view.document_issues
|
||||
.iter()
|
||||
.map(|issue| format!("Document issue: {issue:?}")),
|
||||
);
|
||||
for client in &view.clients {
|
||||
for issue in client.presented_issues() {
|
||||
issues.push(format!("Peer at line {}: {issue:?}", client.line));
|
||||
}
|
||||
}
|
||||
if issues.is_empty() {
|
||||
"No document or peer issues were reported.".to_owned()
|
||||
} else {
|
||||
issues.join("\n")
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle list/detail navigation and return whether the key was consumed.
|
||||
/// Keeping this path independent of worker actions makes its state transitions
|
||||
/// directly testable without starting an application worker.
|
||||
@@ -921,6 +925,7 @@ mod tests {
|
||||
identity: None,
|
||||
label: "unsupported peer".to_owned(),
|
||||
allowed_ips: Vec::new(),
|
||||
has_subnet_routes: false,
|
||||
issues: vec![PeerIssue::MissingIpv4HostRoute],
|
||||
mutable_identity: None,
|
||||
};
|
||||
@@ -933,6 +938,7 @@ mod tests {
|
||||
identity: Some(first),
|
||||
label: "first".to_owned(),
|
||||
allowed_ips: vec!["10.0.0.2/32".to_owned()],
|
||||
has_subnet_routes: false,
|
||||
issues: Vec::new(),
|
||||
mutable_identity: Some(first),
|
||||
},
|
||||
@@ -1007,6 +1013,38 @@ mod tests {
|
||||
assert!(!state.selected_client_mutable());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issues_screen_hides_valid_address_shape_limits_but_keeps_genuine_errors() {
|
||||
let mut view = navigation_view();
|
||||
view.clients.truncate(1);
|
||||
view.clients[0].issues = vec![PeerIssue::UnsupportedAllowedIpShape { field: 0, item: 1 }];
|
||||
view.clients[0].has_subnet_routes = false;
|
||||
let additional_host_only = issue_summary(&view);
|
||||
assert_eq!(
|
||||
additional_host_only,
|
||||
"No document or peer issues were reported."
|
||||
);
|
||||
assert_eq!(
|
||||
view.clients[0].issues,
|
||||
vec![PeerIssue::UnsupportedAllowedIpShape { field: 0, item: 1 }],
|
||||
"presentation must retain the parser issue for safety checks"
|
||||
);
|
||||
|
||||
view.clients[0].issues = vec![PeerIssue::MissingIpv4HostRoute];
|
||||
assert_eq!(
|
||||
issue_summary(&view),
|
||||
"No document or peer issues were reported.",
|
||||
"valid IPv6-only address shape is a capability limit"
|
||||
);
|
||||
|
||||
view.clients[0]
|
||||
.issues
|
||||
.push(PeerIssue::MalformedAllowedIp { field: 0, item: 2 });
|
||||
let mixed = issue_summary(&view);
|
||||
assert!(mixed.contains("MalformedAllowedIp"));
|
||||
assert!(!mixed.contains("UnsupportedAllowedIpShape"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restart_results_render_cancel_success_and_uncertain_failure_honestly() {
|
||||
use crate::app::{RestartFailureKind, RestartReport, RestartStage};
|
||||
|
||||
Reference in New Issue
Block a user