use domain_check_lib::{
get_all_known_tlds, get_available_presets, get_preset_tlds, get_whois_server,
initialize_bootstrap,
};
#[test]
fn test_library_exports_work() {
let all_tlds = get_all_known_tlds();
assert!(!all_tlds.is_empty());
assert!(all_tlds.contains(&"com".to_string()));
assert!(all_tlds.contains(&"org".to_string()));
let startup_tlds = get_preset_tlds("startup").unwrap();
assert!(!startup_tlds.is_empty());
assert!(startup_tlds.contains(&"io".to_string()));
assert!(startup_tlds.contains(&"ai".to_string()));
let presets = get_available_presets();
assert_eq!(presets.len(), 11);
assert!(presets.contains(&"startup"));
assert!(presets.contains(&"enterprise"));
assert!(presets.contains(&"country"));
assert!(presets.contains(&"popular"));
assert!(presets.contains(&"tech"));
assert!(presets.contains(&"creative"));
assert!(presets.contains(&"ecommerce"));
assert!(presets.contains(&"finance"));
assert!(presets.contains(&"web"));
assert!(presets.contains(&"trendy"));
assert!(presets.contains(&"classic"));
}
#[test]
fn test_core_preset_tlds_are_subset_of_all_tlds() {
let all_tlds = get_all_known_tlds();
let core_presets = ["startup", "enterprise", "country", "classic"];
for preset_name in &core_presets {
let preset_tlds = get_preset_tlds(preset_name).unwrap();
for tld in preset_tlds {
assert!(
all_tlds.contains(&tld),
"Core preset '{}' contains TLD '{}' not in all_known_tlds",
preset_name,
tld
);
}
}
}
#[test]
fn test_all_known_tlds_sorted() {
let tlds = get_all_known_tlds();
let mut sorted_tlds = tlds.clone();
sorted_tlds.sort();
assert_eq!(tlds, sorted_tlds, "TLDs should be returned in sorted order");
}
#[test]
fn test_preset_tlds_case_insensitive() {
assert_eq!(get_preset_tlds("startup"), get_preset_tlds("STARTUP"));
assert_eq!(get_preset_tlds("enterprise"), get_preset_tlds("ENTERPRISE"));
assert_eq!(get_preset_tlds("country"), get_preset_tlds("COUNTRY"));
assert_eq!(get_preset_tlds("popular"), get_preset_tlds("POPULAR"));
assert_eq!(get_preset_tlds("tech"), get_preset_tlds("TECH"));
assert_eq!(get_preset_tlds("creative"), get_preset_tlds("CREATIVE"));
assert_eq!(get_preset_tlds("ecommerce"), get_preset_tlds("ECOMMERCE"));
assert_eq!(get_preset_tlds("finance"), get_preset_tlds("FINANCE"));
assert_eq!(get_preset_tlds("web"), get_preset_tlds("WEB"));
assert_eq!(get_preset_tlds("trendy"), get_preset_tlds("TRENDY"));
assert_eq!(get_preset_tlds("classic"), get_preset_tlds("CLASSIC"));
}
#[test]
fn test_preset_tlds_invalid_returns_none() {
assert!(get_preset_tlds("nonexistent").is_none());
assert!(get_preset_tlds("").is_none());
assert!(get_preset_tlds("invalid_preset_name").is_none());
}
#[tokio::test]
async fn test_known_taken_domain_google_com() {
use domain_check_lib::DomainChecker;
let checker = DomainChecker::new();
let result = checker.check_domain("google.com").await.unwrap();
assert_eq!(
result.available,
Some(false),
"google.com must be reported as TAKEN"
);
}
#[tokio::test]
#[ignore]
async fn test_fetch_full_bootstrap_returns_over_1000_entries() {
initialize_bootstrap().await.unwrap();
let tlds = get_all_known_tlds();
assert!(
tlds.len() > 1000,
"Expected >1000 TLDs after bootstrap, got {}",
tlds.len()
);
}
#[tokio::test]
#[ignore]
async fn test_bootstrap_adds_non_hardcoded_tlds() {
initialize_bootstrap().await.unwrap();
let tlds = get_all_known_tlds();
assert!(
tlds.contains(&"museum".to_string()),
"Bootstrap should include .museum TLD"
);
assert!(
tlds.contains(&"travel".to_string()),
"Bootstrap should include .travel TLD"
);
}
#[tokio::test]
#[ignore]
async fn test_initialize_bootstrap_idempotent() {
initialize_bootstrap().await.unwrap();
let count1 = get_all_known_tlds().len();
initialize_bootstrap().await.unwrap();
let count2 = get_all_known_tlds().len();
assert_eq!(
count1, count2,
"Second bootstrap call should not change TLD count"
);
}
#[tokio::test]
#[ignore]
async fn test_bootstrap_results_sorted_and_deduplicated() {
initialize_bootstrap().await.unwrap();
let tlds = get_all_known_tlds();
let mut sorted = tlds.clone();
sorted.sort();
assert_eq!(tlds, sorted, "TLDs must be sorted after bootstrap");
let com_count = tlds.iter().filter(|t| t.as_str() == "com").count();
assert_eq!(
com_count, 1,
"\"com\" should appear exactly once (deduplicated)"
);
}
#[tokio::test]
#[ignore]
async fn test_whois_discovery_and_caching() {
let com_server = get_whois_server("com").await;
assert_eq!(
com_server,
Some("whois.verisign-grs.com".to_string()),
".com WHOIS server should be whois.verisign-grs.com"
);
let org_server = get_whois_server("org").await;
assert!(
org_server.is_some(),
".org should have a WHOIS server via IANA referral"
);
let co_server = get_whois_server("co").await;
assert!(
co_server.is_some(),
".co should have a WHOIS server (it was removed from hardcoded RDAP)"
);
let com_server_cached = get_whois_server("com").await;
assert_eq!(
com_server, com_server_cached,
"Cached result should match first result"
);
}
#[tokio::test]
#[ignore]
async fn test_check_domain_on_non_hardcoded_tld() {
use domain_check_lib::{CheckConfig, DomainChecker};
let config = CheckConfig::default().with_bootstrap(true);
let checker = DomainChecker::with_config(config);
let result = checker.check_domain("nic.museum").await;
assert!(
result.is_ok(),
"Should be able to check .museum domain via bootstrap: {:?}",
result.err()
);
let result = result.unwrap();
assert!(
result.available.is_some(),
"Should get a definitive availability result for nic.museum"
);
}
#[tokio::test]
async fn test_check_domain_no_bootstrap_unknown_tld_falls_back_to_whois() {
use domain_check_lib::{CheckConfig, DomainChecker};
let config = CheckConfig::default()
.with_bootstrap(false)
.with_whois_fallback(true);
let checker = DomainChecker::with_config(config);
let result = checker.check_domain("nic.museum").await;
assert!(
result.is_ok(),
"WHOIS fallback should handle unknown TLDs gracefully"
);
}
#[test]
fn test_default_config_has_bootstrap_enabled() {
use domain_check_lib::CheckConfig;
let config = CheckConfig::default();
assert!(
config.enable_bootstrap,
"Bootstrap should be enabled by default"
);
}
#[test]
fn test_new_exports_accessible() {
let _ = domain_check_lib::initialize_bootstrap;
let _ = domain_check_lib::get_whois_server;
}
#[tokio::test]
async fn test_batch_check_preserves_domain_names_in_errors() {
use domain_check_lib::{CheckConfig, DomainChecker};
let config = CheckConfig::default()
.with_bootstrap(false)
.with_whois_fallback(false);
let checker = DomainChecker::with_config(config);
let domains = vec![
"testdomain.invalidtld1".to_string(),
"testdomain.invalidtld2".to_string(),
"testdomain.invalidtld3".to_string(),
];
let results = checker.check_domains(&domains).await.unwrap();
assert_eq!(results.len(), 3);
assert_eq!(results[0].domain, "testdomain.invalidtld1");
assert_eq!(results[1].domain, "testdomain.invalidtld2");
assert_eq!(results[2].domain, "testdomain.invalidtld3");
let unique_domains: std::collections::HashSet<&str> =
results.iter().map(|r| r.domain.as_str()).collect();
assert_eq!(
unique_domains.len(),
3,
"Each error result must have a unique domain name, not all mapped to domains[0]"
);
}
#[tokio::test]
async fn test_batch_check_preserves_names_mixed_results() {
use domain_check_lib::DomainChecker;
let checker = DomainChecker::new();
let domains = vec![
"google.com".to_string(),
"testxyz.invalidtld999".to_string(),
];
let results = checker.check_domains(&domains).await.unwrap();
assert_eq!(results.len(), 2);
assert_eq!(results[0].domain, "google.com");
assert_eq!(results[1].domain, "testxyz.invalidtld999");
}
#[tokio::test]
#[ignore] async fn test_rdap_404_falls_through_to_whois() {
use domain_check_lib::{CheckConfig, DomainChecker};
let config = CheckConfig::default().with_detailed_info(true);
let checker = DomainChecker::with_config(config);
let result = checker.check_domain("read.moe").await;
assert!(result.is_ok(), "Should not return error: {:?}", result);
let result = result.unwrap();
assert_eq!(
result.available,
Some(false),
"read.moe is registered — WHOIS should confirm it as TAKEN"
);
}
#[tokio::test]
#[ignore] async fn test_rdap_404_no_whois_still_works() {
use domain_check_lib::{CheckConfig, DomainChecker};
let config = CheckConfig::default().with_whois_fallback(false);
let checker = DomainChecker::with_config(config);
let result = checker.check_domain("read.moe").await;
assert!(
result.is_ok(),
"Should return Ok even without WHOIS fallback: {:?}",
result
);
let result = result.unwrap();
assert_eq!(result.available, Some(true));
assert!(
result.error_message.is_some(),
"Should include a warning that result is unverified"
);
}