use runcycles::models::*;
use runcycles::CyclesClient;
use serde_json::json;
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
#[tokio::test]
async fn retry_engine_retries_on_server_error() {
let server = MockServer::start().await;
let client = CyclesClient::builder("key", server.uri())
.retry_enabled(true)
.retry_max_attempts(3)
.build();
Mock::given(method("POST"))
.and(path("/v1/reservations/rsv_retry/commit"))
.respond_with(ResponseTemplate::new(500).set_body_json(json!({
"error": "INTERNAL_ERROR",
"message": "Temporary failure",
"request_id": "req-retry"
})))
.up_to_n_times(1)
.mount(&server)
.await;
Mock::given(method("POST"))
.and(path("/v1/reservations/rsv_retry/commit"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"status": "COMMITTED",
"charged": {"unit": "USD_MICROCENTS", "amount": 5000}
})))
.mount(&server)
.await;
let id = ReservationId::new("rsv_retry");
let req = CommitRequest::builder()
.actual(Amount::usd_microcents(5000))
.build();
let err = client.commit_reservation(&id, &req).await.unwrap_err();
assert!(err.is_retryable());
let resp = client.commit_reservation(&id, &req).await.unwrap();
assert_eq!(resp.status, CommitStatus::Committed);
}