use wiremock::MockServer;
pub async fn setup_mock_server() -> MockServer {
MockServer::start().await
}
#[allow(dead_code)]
pub mod constants {
pub const TEST_TOKEN: &str = "test-token";
pub const BAD_TOKEN: &str = "bad-token";
}
#[cfg(feature = "cloudflare")]
pub mod cloudflare {
use serde_json::{json, Value};
pub const ZONE_ID_1: &str = "aaaabbbbccccdddd1111222233334444";
pub const ZONE_ID_2: &str = "eeeeffffaaaa00001111222233335555";
pub const RECORD_ID_1: &str = "11112222333344445555666677778888";
pub const RECORD_ID_2: &str = "88887777666655554444333322221111";
pub const NEW_RECORD_ID: &str = "99990000aaaabbbbccccddddeeee0000";
pub fn mock_zone_response(id: &str, name: &str) -> Value {
json!({
"success": true,
"errors": [],
"messages": [],
"result": {
"id": id,
"name": name,
"status": "active",
"paused": false,
"type": "full"
}
})
}
pub fn mock_zones_list_response(zones: Vec<(&str, &str)>) -> Value {
json!({
"success": true,
"errors": [],
"messages": [],
"result": zones.iter().map(|(id, name)| json!({
"id": id,
"name": name,
"status": "active",
"paused": false,
"type": "full"
})).collect::<Vec<_>>(),
"result_info": {
"page": 1,
"per_page": 100,
"total_pages": 1,
"count": zones.len(),
"total_count": zones.len()
}
})
}
pub fn mock_record_response(
id: &str,
zone_id: &str,
zone_name: &str,
name: &str,
record_type: &str,
content: &str,
ttl: u32,
) -> Value {
json!({
"success": true,
"errors": [],
"messages": [],
"result": {
"id": id,
"zone_id": zone_id,
"zone_name": zone_name,
"name": name,
"type": record_type,
"content": content,
"proxied": false,
"ttl": ttl
}
})
}
pub fn mock_records_list_response(
records: Vec<(&str, &str, &str, &str, &str, &str, u32)>,
) -> Value {
json!({
"success": true,
"errors": [],
"messages": [],
"result": records.iter().map(|(id, zone_id, zone_name, name, record_type, content, ttl)| json!({
"id": id,
"zone_id": zone_id,
"zone_name": zone_name,
"name": name,
"type": record_type,
"content": content,
"proxied": false,
"ttl": ttl
})).collect::<Vec<_>>(),
"result_info": {
"page": 1,
"per_page": 100,
"total_pages": 1,
"count": records.len(),
"total_count": records.len()
}
})
}
pub fn mock_error_response(code: i32, message: &str) -> Value {
json!({
"success": false,
"errors": [{"code": code, "message": message}],
"messages": [],
"result": null
})
}
pub fn mock_delete_response(id: &str) -> Value {
json!({
"success": true,
"errors": [],
"messages": [],
"result": {
"id": id
}
})
}
}
#[cfg(feature = "namecheap")]
pub mod namecheap {
pub fn mock_get_hosts_response(records: &[(&str, &str, &str, &str, u64)]) -> String {
let mut hosts = String::new();
for (i, (name, record_type, address, host_id, ttl)) in records.iter().enumerate() {
hosts.push_str(&format!(
r#" <Host HostId="{}" Name="{}" Type="{}" Address="{}" MXPref="10" TTL="{}" />"#,
if host_id.is_empty() {
format!("{}", i + 1)
} else {
host_id.to_string()
},
name,
record_type,
address,
ttl,
));
hosts.push('\n');
}
format!(
r#"<?xml version="1.0" encoding="UTF-8"?>
<ApiResponse xmlns="http://api.namecheap.com/xml.response" Status="OK">
<Errors />
<RequestedCommand>namecheap.domains.dns.getHosts</RequestedCommand>
<CommandResponse Type="namecheap.domains.dns.getHosts">
<DomainDNSGetHostsResult Domain="example.com" IsUsingOurDNS="true">
{} </DomainDNSGetHostsResult>
</CommandResponse>
</ApiResponse>"#,
hosts
)
}
pub fn mock_set_hosts_response() -> String {
r#"<?xml version="1.0" encoding="UTF-8"?>
<ApiResponse xmlns="http://api.namecheap.com/xml.response" Status="OK">
<Errors />
<RequestedCommand>namecheap.domains.dns.setHosts</RequestedCommand>
<CommandResponse Type="namecheap.domains.dns.setHosts">
<DomainDNSSetHostsResult Domain="example.com" IsSuccess="true" />
</CommandResponse>
</ApiResponse>"#
.to_string()
}
pub fn mock_rate_limited_response() -> String {
r#"<?xml version="1.0" encoding="UTF-8"?>
<ApiResponse xmlns="http://api.namecheap.com/xml.response" Status="ERROR">
<Errors>
<Error Number="500000">Too many requests. Please try again later.</Error>
</Errors>
<RequestedCommand>namecheap.domains.dns.getHosts</RequestedCommand>
</ApiResponse>"#
.to_string()
}
}
#[cfg(feature = "hetzner")]
pub mod hetzner {
use serde_json::{json, Value};
pub fn mock_zones_response(zones: Vec<(u64, &str, u64)>) -> Value {
json!({
"meta": {
"pagination": {
"page": 1,
"per_page": 25,
"previous_page": null,
"next_page": null,
"last_page": 1,
"total_entries": zones.len()
}
},
"zones": zones.iter().map(|(id, name, ttl)| {
json!({
"id": id,
"name": name,
"mode": "primary",
"ttl": ttl,
"status": "ok",
"record_count": 0
})
}).collect::<Vec<_>>()
})
}
pub fn mock_zone_response(id: u64, name: &str, ttl: u64) -> Value {
json!({
"zone": {
"id": id,
"name": name,
"mode": "primary",
"ttl": ttl,
"status": "ok",
"record_count": 0
}
})
}
pub fn mock_rrsets_response(zone_id: u64, rrsets: Vec<(&str, &str, u64, Vec<&str>)>) -> Value {
let len = rrsets.len();
json!({
"meta": {
"pagination": {
"page": 1,
"per_page": 100,
"last_page": 1,
"total_entries": len
}
},
"rrsets": rrsets.iter().map(|(name, record_type, ttl, values)| {
json!({
"id": format!("{}/{}", name, record_type),
"name": name,
"type": record_type,
"ttl": ttl,
"zone": zone_id,
"records": values.iter().map(|v| json!({"value": v})).collect::<Vec<_>>()
})
}).collect::<Vec<_>>()
})
}
pub fn mock_rrset_response(
zone_id: u64,
name: &str,
record_type: &str,
ttl: u64,
values: Vec<&str>,
) -> Value {
json!({
"rrset": {
"id": format!("{}/{}", name, record_type),
"name": name,
"type": record_type,
"ttl": ttl,
"zone": zone_id,
"records": values.iter().map(|v| json!({"value": v})).collect::<Vec<_>>()
}
})
}
pub fn mock_action_response(id: u64, status: &str) -> Value {
json!({
"action": {
"id": id,
"command": "create_rrset",
"status": status,
"progress": 100
}
})
}
}