@@ -11,6 +11,8 @@ use proxywarden_lib::models::{
|
||||
ActivityLevel, ComponentId, LocalSingBoxConfig, ProxyProtocol, SubscriptionCache,
|
||||
SubscriptionServer, TargetKind,
|
||||
};
|
||||
#[cfg(windows)]
|
||||
use proxywarden_lib::safe_fs;
|
||||
use proxywarden_lib::storage::JsonStorage;
|
||||
use proxywarden_lib::subscription;
|
||||
use serde_json::{json, Map};
|
||||
@@ -342,6 +344,11 @@ fn generate_writes_config_and_local_singbox_target() {
|
||||
assert_eq!(target.port, 1080);
|
||||
assert_eq!(target.requires_component, Some(ComponentId::Singbox));
|
||||
assert_eq!(activity[0].title, "Конфиг Local sing-box создан");
|
||||
#[cfg(windows)]
|
||||
safe_fs::verify_path_protected_for_owner_admin_system(Path::new(
|
||||
&response.generated_config_path,
|
||||
))
|
||||
.expect("generated sing-box config keeps restricted ACL");
|
||||
|
||||
cleanup(&root);
|
||||
}
|
||||
@@ -526,6 +533,111 @@ fn sample_cache() -> SubscriptionCache {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_candidate_fetch_keeps_the_previous_url_cache_and_selection() {
|
||||
struct FailedFetcher;
|
||||
impl SubscriptionFetcher for FailedFetcher {
|
||||
fn fetch_subscription(
|
||||
&self,
|
||||
_: &str,
|
||||
_: &subscription::SubscriptionFetchIdentity,
|
||||
) -> Result<SubscriptionCache, subscription::SubscriptionError> {
|
||||
Err(subscription::SubscriptionError {
|
||||
message: "offline".to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
let root = test_root("candidate-failure");
|
||||
let storage = JsonStorage::new(&root);
|
||||
save_singbox_subscription_to_storage(
|
||||
&storage,
|
||||
SaveSingBoxSubscriptionInputDto {
|
||||
subscription_url: "https://old.example.test/token".into(),
|
||||
},
|
||||
&FixedClock,
|
||||
)
|
||||
.unwrap();
|
||||
storage
|
||||
.write_singbox_subscription_cache(&sample_cache())
|
||||
.unwrap();
|
||||
let before = fs::read(&storage.paths().local_singbox_file).unwrap();
|
||||
let cache_before = fs::read(&storage.paths().singbox_subscription_cache_file).unwrap();
|
||||
assert!(
|
||||
proxywarden_lib::singbox_subscription::fetch_singbox_subscription_candidate(
|
||||
&storage,
|
||||
Some("https://new.example.test/token"),
|
||||
&FailedFetcher,
|
||||
&FixedClock
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
assert_eq!(
|
||||
fs::read(&storage.paths().local_singbox_file).unwrap(),
|
||||
before
|
||||
);
|
||||
assert_eq!(
|
||||
fs::read(&storage.paths().singbox_subscription_cache_file).unwrap(),
|
||||
cache_before
|
||||
);
|
||||
cleanup(&root);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fetch_finishing_after_forget_cannot_resurrect_subscription_or_backup() {
|
||||
struct ForgetDuringFetch<'a>(&'a JsonStorage);
|
||||
impl SubscriptionFetcher for ForgetDuringFetch<'_> {
|
||||
fn fetch_subscription(
|
||||
&self,
|
||||
_: &str,
|
||||
_: &subscription::SubscriptionFetchIdentity,
|
||||
) -> Result<SubscriptionCache, subscription::SubscriptionError> {
|
||||
forget_singbox_subscription_in_storage(self.0, &FixedClock).unwrap();
|
||||
Ok(sample_cache())
|
||||
}
|
||||
}
|
||||
let root = test_root("forget-during-fetch");
|
||||
let storage = JsonStorage::new(&root);
|
||||
save_singbox_subscription_to_storage(
|
||||
&storage,
|
||||
SaveSingBoxSubscriptionInputDto {
|
||||
subscription_url: "https://old.example.test/token".into(),
|
||||
},
|
||||
&FixedClock,
|
||||
)
|
||||
.unwrap();
|
||||
storage
|
||||
.write_singbox_subscription_cache(&sample_cache())
|
||||
.unwrap();
|
||||
storage
|
||||
.write_singbox_subscription_cache(&sample_cache())
|
||||
.unwrap();
|
||||
let error = fetch_singbox_subscription_with_fetcher(
|
||||
&storage,
|
||||
&ForgetDuringFetch(&storage),
|
||||
&FixedClock,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert_eq!(error.code, "configuration_changed");
|
||||
assert!(storage
|
||||
.read_local_singbox_config()
|
||||
.unwrap()
|
||||
.subscription_url
|
||||
.is_none());
|
||||
assert!(storage.read_singbox_subscription_cache().unwrap().is_none());
|
||||
assert!(!proxywarden_lib::safe_fs::backup_path(&storage.paths().local_singbox_file).exists());
|
||||
assert!(!proxywarden_lib::safe_fs::backup_path(
|
||||
&storage.paths().singbox_subscription_cache_file
|
||||
)
|
||||
.exists());
|
||||
fs::remove_file(&storage.paths().local_singbox_file).unwrap();
|
||||
assert!(storage
|
||||
.read_local_singbox_config()
|
||||
.unwrap()
|
||||
.subscription_url
|
||||
.is_none());
|
||||
cleanup(&root);
|
||||
}
|
||||
|
||||
fn sample_cache_with_flag_tag() -> SubscriptionCache {
|
||||
SubscriptionCache {
|
||||
config: json!({
|
||||
|
||||
Reference in New Issue
Block a user