use aws_lite::AwsHttpClient;
use std::env;
fn region() -> String {
env::var("AWS_REGION").unwrap_or_else(|_| "us-east-1".into())
}
#[tokio::test]
#[ignore = "requires AWS credentials"]
async fn test_list_distributions_and_get_config() -> Result<(), Box<dyn std::error::Error>> {
let region = region();
let client = AwsHttpClient::from_default_chain(®ion)?;
let cf = client.cloudfront();
println!("\n=== CloudFront: ListDistributions + GetDistributionConfig ===");
println!("\n[1/3] Listing CloudFront distributions...");
let list = cf.list_distributions().await?;
println!(" Quantity: {}", list.quantity);
println!(" IsTruncated: {}", list.is_truncated);
println!(" Distributions found: {}", list.items.len());
println!("\n[2/3] Verifying list response structure...");
assert!(list.quantity >= 0, "quantity should be non-negative");
if !list.is_truncated {
assert_eq!(
list.quantity as usize,
list.items.len(),
"quantity should match items count when not truncated"
);
}
if let Some(dist) = list.items.first() {
println!("\n[3/3] Getting config for distribution {}...", dist.id);
println!(" Domain: {}", dist.domain_name);
println!(" Status: {}", dist.status);
println!(" PriceClass: {}", dist.price_class);
println!(
" ViewerProtocolPolicy: {}",
dist.default_cache_behavior.viewer_protocol_policy
);
assert!(!dist.id.is_empty(), "distribution ID should not be empty");
assert!(!dist.arn.is_empty(), "distribution ARN should not be empty");
assert!(
dist.arn.starts_with("arn:aws:cloudfront:"),
"ARN should start with arn:aws:cloudfront:, got: {}",
dist.arn
);
let config = cf.get_distribution_config(&dist.id).await?;
println!(" CallerReference: {}", config.caller_reference);
println!(" Enabled: {}", config.enabled);
println!(" Comment: {}", config.comment);
println!(" Origins count: {}", config.origins.quantity);
assert!(
!config.caller_reference.is_empty(),
"caller_reference should not be empty"
);
} else {
println!("\n[3/3] No distributions found — skipping GetDistributionConfig");
println!(" (This is expected in fresh accounts)");
}
println!("\n All CloudFront read operations passed!");
Ok(())
}
#[tokio::test]
#[ignore = "requires AWS credentials"]
async fn test_create_origin_access_control() -> Result<(), Box<dyn std::error::Error>> {
let region = region();
let client = AwsHttpClient::from_default_chain(®ion)?;
let cf = client.cloudfront();
println!("\n=== CloudFront: CreateOriginAccessControl ===");
let unique_suffix = chrono::Utc::now().timestamp();
let oac_name = format!("cloud-lite-test-ralph-oac-{unique_suffix}");
println!("\n[1/2] Creating Origin Access Control '{oac_name}'...");
let oac_config = aws_lite::types::cloudfront::OriginAccessControlConfig {
name: oac_name.clone(),
description: Some("Test OAC created by cloud-lite integration tests".to_string()),
signing_protocol: "sigv4".to_string(),
signing_behavior: "always".to_string(),
origin_access_control_origin_type: "s3".to_string(),
};
let oac = cf.create_origin_access_control(&oac_config).await?;
println!("\n[2/2] Verifying Origin Access Control response...");
assert!(!oac.id.is_empty(), "OAC ID should not be empty");
println!(" OAC ID: {}", oac.id);
let config = oac
.origin_access_control_config
.as_ref()
.expect("OAC config should be present");
assert_eq!(config.name, oac_name);
assert_eq!(config.signing_protocol, "sigv4");
assert_eq!(config.signing_behavior, "always");
assert_eq!(config.origin_access_control_origin_type, "s3");
println!(" Name: {}", config.name);
println!(" SigningProtocol: {}", config.signing_protocol);
println!(" SigningBehavior: {}", config.signing_behavior);
println!(" OriginType: {}", config.origin_access_control_origin_type);
println!(
"\n WARNING: OAC {} created but cannot be auto-cleaned (If-Match header not supported)",
oac.id
);
println!(" Manual cleanup required.");
println!("\n CreateOriginAccessControl passed!");
Ok(())
}