use std::path::Path;
use crate::osm_pbf_file::http_stubs::{start_json_server, start_recording_json_server};
use super::{geofabrik, list_local, resolve_geofabrik_url};
fn tmp(name: &str) -> std::path::PathBuf {
let p = std::env::temp_dir().join(name);
let _ = std::fs::remove_dir_all(&p);
std::fs::create_dir_all(&p).unwrap();
p
}
fn sqlite(name: &str) -> String {
tmp(name).join("test.sqlite3").to_str().unwrap().to_string()
}
#[test]
fn _00_fetches_and_caches_when_no_cache_exists() {
let db = sqlite("ls_t00");
let json = r#"{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"europe/germany","name":"Germany","urls":{"pbf":"http://example.com/germany.osm.pbf"}}},{"type":"Feature","properties":{"id":"europe/france","name":"France","urls":{"pbf":"http://example.com/france.osm.pbf"}}}]}"#.to_string();
let url = start_json_server(json);
let items = geofabrik(&db, false, &url);
assert_eq!(items.len(), 2);
assert_eq!(items[0].id, "europe/france");
assert_eq!(items[0].url, "http://example.com/france.osm.pbf");
assert_eq!(items[1].id, "europe/germany");
assert!(Path::new(&db).exists());
}
#[test]
fn _01_returns_cached_without_refetching() {
let db = sqlite("ls_t01");
let json = r#"{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"asia/japan","name":"Japan","urls":{"pbf":"http://example.com/japan.osm.pbf"}}}]}"#.to_string();
let (url, requests) = start_recording_json_server(json);
geofabrik(&db, false, &url);
let after_first = requests.lock().unwrap().len();
geofabrik(&db, false, &url);
assert_eq!(requests.lock().unwrap().len(), after_first);
}
#[test]
fn _02_recreate_cache_forces_refetch() {
let db = sqlite("ls_t02");
let json = r#"{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"africa/kenya","name":"Kenya","urls":{"pbf":"http://example.com/kenya.osm.pbf"}}}]}"#.to_string();
let (url, requests) = start_recording_json_server(json);
geofabrik(&db, false, &url);
let after_first = requests.lock().unwrap().len();
geofabrik(&db, true, &url);
assert!(requests.lock().unwrap().len() > after_first);
}
#[test]
fn _03_feature_without_pbf_url_has_dash_url() {
let db = sqlite("ls_t03");
let json = r#"{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"oceania/australia","name":"Australia"}}]}"#.to_string();
let url = start_json_server(json);
let items = geofabrik(&db, false, &url);
assert_eq!(items.len(), 1);
assert_eq!(items[0].url, "-");
}
#[test]
fn _04_resolve_geofabrik_url_returns_url_for_known_id() {
let db = sqlite("ls_t04");
let json = r#"{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"south-america/brazil","name":"Brazil","urls":{"pbf":"http://example.com/brazil.osm.pbf"}}}]}"#.to_string();
let url = start_json_server(json);
let result = resolve_geofabrik_url(&db, "south-america/brazil", &url);
assert_eq!(result.as_deref(), Some("http://example.com/brazil.osm.pbf"));
}
#[test]
fn _05_resolve_geofabrik_url_returns_none_for_unknown_id() {
let db = sqlite("ls_t05");
let json = r#"{"type":"FeatureCollection","features":[]}"#.to_string();
let url = start_json_server(json);
let result = resolve_geofabrik_url(&db, "nonexistent/region", &url);
assert!(result.is_none());
}
#[test]
fn _06_resolve_geofabrik_url_returns_none_for_entry_without_url() {
let db = sqlite("ls_t06");
let json = r#"{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"oceania/australia","name":"Australia"}}]}"#.to_string();
let url = start_json_server(json);
let result = resolve_geofabrik_url(&db, "oceania/australia", &url);
assert!(result.is_none());
}
#[test]
fn _07_list_local_returns_empty_when_no_pbf_dir() {
let dir = tmp("ls_t07");
let items = list_local(dir.to_str().unwrap());
assert!(items.is_empty());
}
#[test]
fn _08_list_local_returns_sorted_pbf_files() {
let dir = tmp("ls_t08");
std::fs::write(dir.join("brazil.osm.pbf"), b"fake").unwrap();
std::fs::write(dir.join("andorra.osm.pbf"), b"fake content longer").unwrap();
std::fs::write(dir.join("readme.txt"), b"ignored").unwrap();
let items = list_local(dir.to_str().unwrap());
assert_eq!(items.len(), 2);
assert_eq!(items[0].path.file_name().unwrap(), "andorra.osm.pbf");
assert_eq!(items[1].path.file_name().unwrap(), "brazil.osm.pbf");
assert_eq!(items[0].size_bytes, 19);
assert!(Path::new(&items[0].path).exists());
}
#[test]
fn _09_resolve_geofabrik_url_uses_cache_without_refetching() {
let db = sqlite("ls_t09");
let json = r#"{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"europe/spain","name":"Spain","urls":{"pbf":"http://example.com/spain.osm.pbf"}}}]}"#.to_string();
let (url, requests) = start_recording_json_server(json);
geofabrik(&db, false, &url);
let after_geofabrik = requests.lock().unwrap().len();
let result = resolve_geofabrik_url(&db, "europe/spain", &url);
assert_eq!(result.as_deref(), Some("http://example.com/spain.osm.pbf"));
assert_eq!(requests.lock().unwrap().len(), after_geofabrik);
}
#[test]
fn _10_list_local_returns_empty_for_nonexistent_path() {
let dir = tmp("ls_t10");
let missing = dir.join("does_not_exist");
let items = list_local(missing.to_str().unwrap());
assert!(items.is_empty());
}
#[test]
fn _11_sends_custom_user_agent_header() {
let db = sqlite("ls_t11");
let json = r#"{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"europe/spain","name":"Spain","urls":{"pbf":"http://example.com/spain.osm.pbf"}}}]}"#.to_string();
let (url, requests) = start_recording_json_server(json);
geofabrik(&db, false, &url);
let requests = requests.lock().unwrap();
let user_agent = requests[0]
.lines()
.find(|l| l.to_lowercase().starts_with("user-agent:"))
.and_then(|l| l.split_once(':').map(|x| x.1))
.map(|v| v.trim().to_string());
assert_eq!(
user_agent,
Some(format!("geolite/{}", env!("CARGO_PKG_VERSION")))
);
}