use reqwest::Client;
use serde_json::{json, Value};
use std::collections::HashMap;
use std::process::Command;
use std::sync::Once;
pub const WIREMOCK_BASE_URL: &str = "http://localhost:8080";
const WIREMOCK_ADMIN_URL: &str = "http://localhost:8080/__admin";
const WIREMOCK_COMPOSE_FILE: &str = "wiremock/docker-compose.test.yml";
static START: Once = Once::new();
fn is_wiremock_running() -> bool {
Command::new("curl")
.args(["-s", "-f", &format!("{}/__admin/health", WIREMOCK_BASE_URL)])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
}
#[ctor::ctor]
fn start_wiremock() {
if std::env::var("RUN_WIRE_TESTS").as_deref() == Ok("true") {
START.call_once(|| {
if !std::path::Path::new(WIREMOCK_COMPOSE_FILE).exists() {
return;
}
if is_wiremock_running() {
return;
}
println!("Starting WireMock container...");
let status = Command::new("docker")
.args(["compose", "-f", WIREMOCK_COMPOSE_FILE, "up", "-d", "--wait"])
.status();
if let Err(e) = status {
eprintln!("Failed to start WireMock container: {}", e);
}
});
}
}
pub async fn reset_wiremock_requests() -> Result<(), Box<dyn std::error::Error>> {
Client::new()
.delete(format!("{}/requests", WIREMOCK_ADMIN_URL))
.send()
.await?;
Ok(())
}
pub async fn verify_request_count(
method: &str,
url_path: &str,
query_params: Option<HashMap<String, String>>,
expected: usize,
) -> Result<(), Box<dyn std::error::Error>> {
let mut request_body = json!({
"method": method,
"urlPath": url_path,
});
if let Some(params) = query_params {
let query_parameters: Value = params
.into_iter()
.map(|(k, v)| (k, json!({"equalTo": v})))
.collect();
request_body["queryParameters"] = query_parameters;
}
let response = Client::new()
.post(format!("{}/requests/find", WIREMOCK_ADMIN_URL))
.json(&request_body)
.send()
.await?;
let result: Value = response.json().await?;
let requests = result["requests"]
.as_array()
.ok_or("Invalid response from WireMock")?;
assert_eq!(
requests.len(),
expected,
"Expected {} requests, found {}",
expected,
requests.len()
);
Ok(())
}