Fix timestamp formats conflict

This commit is contained in:
2026-10-27 20:42:12 +02:00
parent 6d8d6d572d
commit af2d061880
4 changed files with 181 additions and 11 deletions
+106
View File
@@ -9,6 +9,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;
use std::time::{Duration, Instant};
use crossterm::event::KeyCode;
use wireguard_admin::app::{FirstIssueAttempt, RestartChoice, RestartStage};
use wireguard_admin::backup::BackupReason;
use wireguard_admin::config::{ResolvedSettings, SettingsFile};
@@ -19,6 +20,7 @@ use wireguard_admin::tui::events::{
ApplicationWorker, CommandResult, FirstIssueStatus, QrStatus, SecretText, SensitiveCommand,
ShutdownProgress, StatisticsReader, UiCommand, WorkerConfig, WorkerEvent,
};
use wireguard_admin::tui::forms::{FormAction, FormController};
use wireguard_admin::vault::WireGuardPrivateKey;
const SETTINGS: &str = r#"
@@ -528,6 +530,110 @@ fn worker_setup_create_commit_and_delivery_keep_saved_and_runtime_boundaries() {
finish(worker);
}
#[test]
fn create_form_submits_automatic_dual_stack_client_without_changing_saved_state() {
let fixture = fixture();
let reader = CountingStatistics::default();
let reads = Arc::clone(&reader.0);
let mut worker = worker(&fixture, reader);
let setup = worker
.submit_sensitive(SensitiveCommand::PrepareInitialSetup(SecretText::new(
"synthetic vault password".to_owned(),
)))
.expect("setup submitted");
assert!(matches!(
wait_for(&mut worker, setup.request_id),
WorkerEvent::OperationFinished {
result: Ok(CommandResult::InitialSetupPrepared(_)),
..
}
));
let saved_before_create = fixture.store.read_saved().expect("saved state reads");
let mut form = FormController::default();
form.open_create();
for character in "form-created device".chars() {
assert!(matches!(
form.handle_key(KeyCode::Char(character)),
FormAction::None
));
}
assert!(matches!(form.handle_key(KeyCode::Enter), FormAction::None));
assert!(matches!(form.handle_key(KeyCode::Enter), FormAction::None));
let FormAction::Submit(command @ UiCommand::CreateClient { .. }) =
form.handle_key(KeyCode::Enter)
else {
panic!("blank address fields submit an automatically addressed client");
};
let UiCommand::CreateClient {
alias,
manual_addresses,
created_utc,
} = &command
else {
unreachable!();
};
assert_eq!(alias, "form-created device");
assert!(manual_addresses.is_none());
let timestamp = created_utc.as_deref().expect("form includes creation time");
assert!(wireguard_admin::wireguard::metadata::render_block(alias, Some(timestamp)).is_ok());
let operation = worker.submit(command).expect("form command accepted");
let (identity, view) = match wait_for(&mut worker, operation.request_id) {
WorkerEvent::OperationFinished { result, view, .. } => {
let CommandResult::ClientCreated(identity) = result.expect("create succeeds") else {
panic!("create returns client identity");
};
(identity, view)
}
_ => unreachable!("wait_for returns the requested completion"),
};
let row = view
.client_states
.get(&identity)
.expect("created client appears in draft projection");
assert!(
row.saved.is_none(),
"client remains absent from saved state"
);
let draft = row.draft.as_ref().expect("created client is in draft");
assert_eq!(draft.alias, "form-created device");
assert_eq!(
draft.addresses.ipv4,
"10.20.0.2".parse::<std::net::Ipv4Addr>().unwrap()
);
let ipv6_range = "fd20::/64".parse::<ipnet::Ipv6Net>().unwrap();
assert!(
draft
.addresses
.ipv6
.is_some_and(|address| ipv6_range.contains(&address)),
"automatic allocation includes an address from the configured IPv6 range"
);
let saved_after_create = fixture
.store
.read_saved()
.expect("saved state remains readable");
assert_eq!(saved_after_create.settings, saved_before_create.settings);
assert_eq!(
saved_after_create.server_config,
saved_before_create.server_config
);
assert_eq!(
saved_after_create.internal_state,
saved_before_create.internal_state
);
assert_eq!(saved_after_create.vault, saved_before_create.vault);
assert_eq!(
reads.load(Ordering::SeqCst),
0,
"no runtime restart/read occurs"
);
finish(worker);
}
#[test]
fn worker_backup_restore_preview_cancel_and_confirm_are_separate_saved_operations() {
let fixture = fixture();