@@ -14,6 +14,8 @@ use proxywarden_lib::models::{
|
||||
Protocol, ProxyProtocol, SubscriptionCache, SubscriptionServer, Target, TargetInput,
|
||||
TargetKind,
|
||||
};
|
||||
#[cfg(windows)]
|
||||
use proxywarden_lib::safe_fs;
|
||||
use proxywarden_lib::storage::JsonStorage;
|
||||
use std::{cell::Cell, fs, path::Path};
|
||||
|
||||
@@ -44,6 +46,9 @@ fn external_apply_commits_one_source_state_without_service_control() {
|
||||
target.id == "main-proxy" && target.host == "proxy.example.test" && target.port == 1080
|
||||
}));
|
||||
assert!(Path::new(&result.generated_config_path).exists());
|
||||
#[cfg(windows)]
|
||||
safe_fs::verify_path_protected_for_owner_admin_system(Path::new(&result.generated_config_path))
|
||||
.expect("generated config keeps restricted ACL");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -169,6 +174,15 @@ fn helper_failure_rolls_back_source_and_generated_artifact() {
|
||||
fs::read(&generated_path).expect("generated after"),
|
||||
b"old-generated"
|
||||
);
|
||||
#[cfg(windows)]
|
||||
{
|
||||
safe_fs::verify_path_protected_for_owner_admin_system(&generated_path)
|
||||
.expect("rollback keeps generated config restricted");
|
||||
assert!(
|
||||
!safe_fs::backup_path(&generated_path).exists(),
|
||||
"rollback restores prior absence of backup"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -213,6 +227,7 @@ fn local_apply_with_missing_running_service_stops_at_preflight() {
|
||||
let error = run_apply(
|
||||
&fixture.storage,
|
||||
ApplyConfigurationInput {
|
||||
expected_revision: None,
|
||||
route_mode: ApplyRouteMode::LocalSingbox,
|
||||
profile: profile_input(),
|
||||
external_target: None,
|
||||
@@ -230,8 +245,61 @@ fn local_apply_with_missing_running_service_stops_at_preflight() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn editing_shared_target_preserves_the_other_profile_and_target() {
|
||||
let fixture = ApplyFixture::new("shared-target");
|
||||
fixture.seed_old_state();
|
||||
let before_profiles = fixture.storage.read_profiles().unwrap();
|
||||
let before_targets = fixture.storage.read_targets().unwrap();
|
||||
let mut input = external_input();
|
||||
input.disable_other_profiles = false;
|
||||
input.external_target.as_mut().unwrap().id = Some("legacy-target".into());
|
||||
input.profile.protocols = vec!["TCP".into()];
|
||||
input.profile.items = vec![ProfileItemInput {
|
||||
item_type: "folder".into(),
|
||||
value: r"C:\Games".into(),
|
||||
recursive: Some(false),
|
||||
}];
|
||||
run_apply(&fixture.storage, input, &RecordingHelper::success()).unwrap();
|
||||
let profiles = fixture.storage.read_profiles().unwrap();
|
||||
let targets = fixture.storage.read_targets().unwrap();
|
||||
assert_eq!(profiles[0], before_profiles[0]);
|
||||
assert_eq!(targets[0], before_targets[0]);
|
||||
let edited = profiles.iter().find(|p| p.id == "main-profile").unwrap();
|
||||
assert_ne!(edited.target_id, "legacy-target");
|
||||
assert_eq!(edited.protocols, vec![Protocol::Tcp]);
|
||||
assert!(!edited.items[0].recursive);
|
||||
assert_eq!(
|
||||
targets
|
||||
.iter()
|
||||
.find(|t| t.id == edited.target_id)
|
||||
.unwrap()
|
||||
.host,
|
||||
"proxy.example.test"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clearing_last_profile_requires_explicit_stop_and_does_not_call_helper() {
|
||||
let fixture = ApplyFixture::new("clear-running");
|
||||
fixture.seed_old_state();
|
||||
let before = fixture.storage.read_profiles().unwrap();
|
||||
let mut input = external_input();
|
||||
input.profile.id = Some("legacy".into());
|
||||
input.profile.target_id = "legacy-target".into();
|
||||
input.profile.enabled = false;
|
||||
input.profile.items.clear();
|
||||
input.disable_other_profiles = false;
|
||||
let helper = RecordingHelper::success();
|
||||
let error = run_apply(&fixture.storage, input, &helper).unwrap_err();
|
||||
assert_eq!(error.code(), "stop_before_clearing_route");
|
||||
assert_eq!(helper.calls.get(), 0);
|
||||
assert_eq!(fixture.storage.read_profiles().unwrap(), before);
|
||||
}
|
||||
|
||||
fn external_input() -> ApplyConfigurationInput {
|
||||
ApplyConfigurationInput {
|
||||
expected_revision: None,
|
||||
route_mode: ApplyRouteMode::External,
|
||||
profile: profile_input(),
|
||||
external_target: Some(TargetInput {
|
||||
@@ -299,6 +367,7 @@ fn test_proxyfier() -> DetectedProxyfier {
|
||||
running: true,
|
||||
service_name: Some("ProxiFyreService".to_string()),
|
||||
service_status: Some("running".to_string()),
|
||||
version: Some("2.2.1.0".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user