use redis_cloud::CloudClient;
use redis_cloud::databases::DatabaseCreateRequest;
use redis_enterprise::EnterpriseClient;
use redisctl_core::CoreError;
use redisctl_core::cloud::{create_database_and_wait, delete_database_and_wait};
use redisctl_core::enterprise::flush_database_and_wait;
use std::time::Duration;
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
fn cloud_client(uri: String) -> CloudClient {
CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(uri)
.build()
.unwrap()
}
fn enterprise_client(uri: String) -> EnterpriseClient {
EnterpriseClient::builder()
.base_url(uri)
.username("test-user".to_string())
.password("test-pass".to_string())
.insecure(true)
.build()
.unwrap()
}
#[tokio::test]
async fn cloud_delete_database_and_wait_happy_path() {
let mock_server = MockServer::start().await;
Mock::given(method("DELETE"))
.and(path("/subscriptions/1/databases/2"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"taskId": "task-1"
})))
.mount(&mock_server)
.await;
Mock::given(method("GET"))
.and(path("/tasks/task-1"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"taskId": "task-1",
"status": "processing-completed",
"response": {"resourceId": 2}
})))
.mount(&mock_server)
.await;
let client = cloud_client(mock_server.uri());
let result = delete_database_and_wait(&client, 1, 2, Duration::from_secs(5), None).await;
assert!(result.is_ok(), "expected Ok(()), got {result:?}");
}
#[tokio::test]
async fn cloud_delete_database_and_wait_task_failure() {
let mock_server = MockServer::start().await;
Mock::given(method("DELETE"))
.and(path("/subscriptions/1/databases/2"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"taskId": "task-1"
})))
.mount(&mock_server)
.await;
Mock::given(method("GET"))
.and(path("/tasks/task-1"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"taskId": "task-1",
"status": "processing-error",
"response": {"error": "Something went wrong"}
})))
.mount(&mock_server)
.await;
let client = cloud_client(mock_server.uri());
let result = delete_database_and_wait(&client, 1, 2, Duration::from_secs(5), None).await;
match result {
Err(CoreError::TaskFailed(msg)) => {
assert_eq!(msg, "Something went wrong");
}
other => panic!("expected TaskFailed, got {other:?}"),
}
}
#[tokio::test]
async fn cloud_create_database_and_wait_happy_path() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/subscriptions/1/databases"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"taskId": "task-1"
})))
.mount(&mock_server)
.await;
Mock::given(method("GET"))
.and(path("/tasks/task-1"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"taskId": "task-1",
"status": "processing-completed",
"response": {"resourceId": 42}
})))
.mount(&mock_server)
.await;
Mock::given(method("GET"))
.and(path("/subscriptions/1/databases/42"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"databaseId": 42,
"name": "test-db",
"status": "active"
})))
.mount(&mock_server)
.await;
let request = DatabaseCreateRequest::builder()
.name("test-db")
.memory_limit_in_gb(1.0)
.build();
let client = cloud_client(mock_server.uri());
let result = create_database_and_wait(&client, 1, &request, Duration::from_secs(5), None).await;
match result {
Ok(db) => {
assert_eq!(db.database_id, 42);
assert_eq!(db.name.as_deref(), Some("test-db"));
}
other => panic!("expected Ok(database), got {other:?}"),
}
}
#[tokio::test]
async fn enterprise_flush_database_and_wait_happy_path() {
let mock_server = MockServer::start().await;
Mock::given(method("PUT"))
.and(path("/v1/bdbs/1/flush"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"action_uid": "action-1"
})))
.mount(&mock_server)
.await;
Mock::given(method("GET"))
.and(path("/v1/actions/action-1"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"action_uid": "action-1",
"name": "flush",
"status": "completed",
"progress": "100"
})))
.mount(&mock_server)
.await;
let client = enterprise_client(mock_server.uri());
let result = flush_database_and_wait(&client, 1, Duration::from_secs(5), None).await;
assert!(result.is_ok(), "expected Ok(()), got {result:?}");
}
#[tokio::test]
async fn enterprise_flush_database_and_wait_task_failure() {
let mock_server = MockServer::start().await;
Mock::given(method("PUT"))
.and(path("/v1/bdbs/1/flush"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"action_uid": "action-1"
})))
.mount(&mock_server)
.await;
Mock::given(method("GET"))
.and(path("/v1/actions/action-1"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"action_uid": "action-1",
"name": "flush",
"status": "failed",
"error": "flush failed: database is locked"
})))
.mount(&mock_server)
.await;
let client = enterprise_client(mock_server.uri());
let result = flush_database_and_wait(&client, 1, Duration::from_secs(5), None).await;
match result {
Err(CoreError::TaskFailed(msg)) => {
assert_eq!(msg, "flush failed: database is locked");
}
other => panic!("expected TaskFailed, got {other:?}"),
}
}