use intel_dcap_api::{ApiClient, ApiVersion, CaType, IntelApiError, UpdateType};
use mockito::Server;
use reqwest::Client;
async fn create_test_client(base_url: &str) -> ApiClient {
ApiClient::new_with_base_url(base_url).expect("Failed to create client")
}
#[tokio::test]
async fn test_simple_request() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/test")
.with_status(200)
.with_body("test")
.create_async()
.await;
let client = Client::new();
let resp = client
.get(format!("{}/test", server.url()))
.send()
.await
.unwrap();
assert_eq!(resp.status(), 200);
assert_eq!(resp.text().await.unwrap(), "test");
}
#[tokio::test]
async fn test_tdx_tcb_minimal() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/tdx/certification/v4/tcb")
.match_query(mockito::Matcher::UrlEncoded(
"fmspc".into(),
"test123".into(),
))
.with_status(200)
.with_header("TCB-Info-Issuer-Chain", "test-cert")
.with_body("{}")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client.get_tdx_tcb_info("test123", None, None).await;
match &result {
Ok(resp) => {
assert_eq!(resp.tcb_info_json, "{}");
assert_eq!(resp.issuer_chain, "test-cert");
}
Err(e) => {
eprintln!("Error: {:?}", e);
panic!("Request failed");
}
}
}
#[tokio::test]
async fn test_sgx_qe_identity_minimal() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/sgx/certification/v4/qe/identity")
.with_status(200)
.with_header("SGX-Enclave-Identity-Issuer-Chain", "test-cert")
.with_body("{}")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client.get_sgx_qe_identity(None, None).await;
assert!(result.is_ok());
let resp = result.unwrap();
assert_eq!(resp.enclave_identity_json, "{}");
assert_eq!(resp.issuer_chain, "test-cert");
}
#[tokio::test]
async fn test_pck_crl_minimal() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/sgx/certification/v4/pckcrl")
.match_query(mockito::Matcher::UrlEncoded(
"ca".into(),
"processor".into(),
))
.with_status(200)
.with_header("SGX-PCK-CRL-Issuer-Chain", "test-cert")
.with_body("test-crl")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client.get_pck_crl(CaType::Processor, None).await;
assert!(result.is_ok());
let resp = result.unwrap();
assert_eq!(String::from_utf8_lossy(&resp.crl_data), "test-crl");
assert_eq!(resp.issuer_chain, "test-cert");
}
#[tokio::test]
async fn test_error_handling() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/sgx/certification/v4/tcb")
.match_query(mockito::Matcher::UrlEncoded("fmspc".into(), "bad".into()))
.with_status(404)
.with_header("Request-ID", "test-123")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client.get_sgx_tcb_info("bad", None, None).await;
assert!(result.is_err());
match result.unwrap_err() {
IntelApiError::ApiError {
status, request_id, ..
} => {
assert_eq!(status.as_u16(), 404);
assert_eq!(request_id, "test-123");
}
_ => panic!("Wrong error type"),
}
}
#[tokio::test]
async fn test_update_types() {
let mut server = Server::new_async().await;
let _m1 = server
.mock("GET", "/tdx/certification/v4/tcb")
.match_query(mockito::Matcher::AllOf(vec![
mockito::Matcher::UrlEncoded("fmspc".into(), "test".into()),
mockito::Matcher::UrlEncoded("update".into(), "early".into()),
]))
.with_status(200)
.with_header("TCB-Info-Issuer-Chain", "cert")
.with_body("{\"early\":true}")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client
.get_tdx_tcb_info("test", Some(UpdateType::Early), None)
.await;
assert!(result.is_ok());
assert_eq!(result.unwrap().tcb_info_json, "{\"early\":true}");
let _m2 = server
.mock("GET", "/tdx/certification/v4/tcb")
.match_query(mockito::Matcher::AllOf(vec![
mockito::Matcher::UrlEncoded("fmspc".into(), "test".into()),
mockito::Matcher::UrlEncoded("update".into(), "standard".into()),
]))
.with_status(200)
.with_header("TCB-Info-Issuer-Chain", "cert")
.with_body("{\"standard\":true}")
.create_async()
.await;
let result2 = client
.get_tdx_tcb_info("test", Some(UpdateType::Standard), None)
.await;
assert!(result2.is_ok());
assert_eq!(result2.unwrap().tcb_info_json, "{\"standard\":true}");
}
#[tokio::test]
async fn test_v3_api_headers() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/sgx/certification/v3/pckcrl")
.match_query(mockito::Matcher::UrlEncoded("ca".into(), "platform".into()))
.with_status(200)
.with_header("SGX-PCK-CRL-Issuer-Chain", "v3-cert")
.with_body("v3-crl-data")
.create_async()
.await;
let client = ApiClient::new_with_options(server.url(), ApiVersion::V3).unwrap();
let result = client.get_pck_crl(CaType::Platform, None).await;
assert!(result.is_ok());
let resp = result.unwrap();
assert_eq!(String::from_utf8_lossy(&resp.crl_data), "v3-crl-data");
assert_eq!(resp.issuer_chain, "v3-cert");
}
#[tokio::test]
async fn test_sgx_qve_identity() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/sgx/certification/v4/qve/identity")
.with_status(200)
.with_header("SGX-Enclave-Identity-Issuer-Chain", "qve-cert")
.with_body("{\"id\":\"QVE\"}")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client.get_sgx_qve_identity(None, None).await;
assert!(result.is_ok());
let resp = result.unwrap();
assert_eq!(resp.enclave_identity_json, "{\"id\":\"QVE\"}");
assert_eq!(resp.issuer_chain, "qve-cert");
}
#[tokio::test]
async fn test_tdx_qe_identity() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/tdx/certification/v4/qe/identity")
.with_status(200)
.with_header("SGX-Enclave-Identity-Issuer-Chain", "tdx-qe-cert")
.with_body("{\"id\":\"TDX-QE\"}")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client.get_tdx_qe_identity(None, None).await;
assert!(result.is_ok());
let resp = result.unwrap();
assert_eq!(resp.enclave_identity_json, "{\"id\":\"TDX-QE\"}");
assert_eq!(resp.issuer_chain, "tdx-qe-cert");
}
#[tokio::test]
async fn test_error_with_details() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/sgx/certification/v4/pckcert")
.match_query(mockito::Matcher::Any)
.with_status(400)
.with_header("Request-ID", "error-req-123")
.with_header("Error-Code", "InvalidParameter")
.with_header("Error-Message", "PPID format is invalid")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client
.get_pck_certificate_by_ppid("bad", "bad", "bad", "bad", None, None)
.await;
assert!(result.is_err());
match result.unwrap_err() {
IntelApiError::ApiError {
status,
request_id,
error_code,
error_message,
} => {
assert_eq!(status.as_u16(), 400);
assert_eq!(request_id, "error-req-123");
assert_eq!(error_code.as_deref(), Some("InvalidParameter"));
assert_eq!(error_message.as_deref(), Some("PPID format is invalid"));
}
_ => panic!("Wrong error type"),
}
}
#[tokio::test]
async fn test_sgx_tcb_info() {
let mut server = Server::new_async().await;
let _m = server
.mock("GET", "/sgx/certification/v4/tcb")
.match_query(mockito::Matcher::UrlEncoded(
"fmspc".into(),
"00606A6A0000".into(),
))
.with_status(200)
.with_header("TCB-Info-Issuer-Chain", "sgx-tcb-cert")
.with_body("{\"tcbInfo\":{\"fmspc\":\"00606A6A0000\"}}")
.create_async()
.await;
let client = create_test_client(&server.url()).await;
let result = client.get_sgx_tcb_info("00606A6A0000", None, None).await;
assert!(result.is_ok());
let resp = result.unwrap();
assert_eq!(
resp.tcb_info_json,
"{\"tcbInfo\":{\"fmspc\":\"00606A6A0000\"}}"
);
assert_eq!(resp.issuer_chain, "sgx-tcb-cert");
}