use redis_cloud::{CloudClient, FixedDatabaseHandler};
use serde_json::json;
use wiremock::matchers::{header, method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
#[tokio::test]
async fn test_get_fixed_subscription_databases() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/fixed/subscriptions/123/databases"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"accountId": 456,
"subscription": {
"subscriptionId": 123,
"numberOfDatabases": 2,
"databases": [
{
"databaseId": 51324587,
"name": "bdb",
"protocol": "stack",
"provider": "AWS",
"region": "us-east-1",
"redisVersion": "7.4",
"status": "active",
"planMemoryLimit": 250,
"memoryLimitMeasurementUnit": "MB",
"memoryUsedInMb": 1,
"memoryStorage": "ram",
"dataPersistence": "none",
"replication": true,
"dataEvictionPolicy": "noeviction",
},
{
"databaseId": 51324586,
"name": "firstDB",
"protocol": "stack",
"provider": "AWS",
"region": "us-east-1",
"status": "active",
"planMemoryLimit": 250,
"memoryLimitMeasurementUnit": "MB",
"memoryStorage": "ram",
},
],
"links": []
},
"links": [
{
"href": "https://api.redislabs.com/v1/fixed/subscriptions/123/databases/1",
"rel": "database",
"type": "GET"
}
],
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let result = handler.list(123, None, None).await.unwrap();
assert_eq!(result.account_id, Some(456));
assert!(result.links.is_some());
let subscription = result
.subscription
.expect("response should include the subscription object");
assert_eq!(subscription.subscription_id, Some(123));
assert_eq!(subscription.number_of_databases, Some(2));
assert_eq!(subscription.databases.len(), 2);
assert_eq!(subscription.databases[0].database_id, Some(51324587));
assert_eq!(subscription.databases[0].name.as_deref(), Some("bdb"));
assert_eq!(subscription.databases[1].database_id, Some(51324586));
assert_eq!(subscription.databases[1].name.as_deref(), Some("firstDB"));
}
#[tokio::test]
async fn test_create_fixed_database() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/fixed/subscriptions/123/databases"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(202).set_body_json(json!({
"taskId": "task-create-fixed-db",
"commandType": "CREATE_FIXED_DATABASE",
"status": "processing",
"description": "Creating fixed database",
"timestamp": "2024-01-01T00:00:00Z",
"response": {
"resourceId": 789
}
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let request = redis_cloud::fixed_databases::FixedDatabaseCreateRequest {
name: "fixed-test-database".to_string(),
subscription_id: None,
protocol: None,
memory_limit_in_gb: Some(1.0),
dataset_size_in_gb: None,
support_oss_cluster_api: None,
redis_version: None,
resp_version: None,
use_external_endpoint_for_oss_cluster_api: None,
enable_database_clustering: None,
number_of_shards: None,
data_persistence: None,
data_eviction_policy: Some("noeviction".to_string()),
replication: Some(true),
periodic_backup_path: None,
source_ips: None,
regex_rules: None,
replica_of: None,
replica: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
password: None,
alerts: None,
modules: None,
command_type: None,
};
let result = handler.create(123, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-create-fixed-db".to_string()));
assert_eq!(
result.command_type,
Some("CREATE_FIXED_DATABASE".to_string())
);
}
#[tokio::test]
async fn test_fixed_database_update() {
let mock_server = MockServer::start().await;
Mock::given(method("PUT"))
.and(path("/fixed/subscriptions/123/databases/456"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(202).set_body_json(json!({
"taskId": "task-update-fixed-db",
"commandType": "UPDATE_FIXED_DATABASE",
"status": "processing",
"description": "Updating fixed database configuration"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let request = redis_cloud::fixed_databases::FixedDatabaseUpdateRequest {
subscription_id: None,
database_id: None,
name: Some("updated-fixed-database".to_string()),
memory_limit_in_gb: Some(2.0),
dataset_size_in_gb: None,
data_persistence: None,
data_eviction_policy: Some("allkeys-lru".to_string()),
replication: None,
resp_version: None,
support_oss_cluster_api: None,
use_external_endpoint_for_oss_cluster_api: None,
password: None,
enable_database_clustering: None,
number_of_shards: None,
periodic_backup_path: None,
source_ips: None,
regex_rules: None,
replica_of: None,
replica: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
enable_default_user: None,
alerts: None,
command_type: None,
};
let result = handler.update(123, 456, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-update-fixed-db".to_string()));
}
#[tokio::test]
async fn test_delete_fixed_database() {
let mock_server = MockServer::start().await;
Mock::given(method("DELETE"))
.and(path("/fixed/subscriptions/123/databases/456"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(202).set_body_json(json!({
"taskId": "task-delete-fixed-db",
"commandType": "DELETE_FIXED_DATABASE",
"status": "processing",
"description": "Deleting fixed database"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let result = handler.delete_by_id(123, 456).await.unwrap();
assert_eq!(result.task_id, Some("task-delete-fixed-db".to_string()));
assert_eq!(
result.command_type,
Some("DELETE_FIXED_DATABASE".to_string())
);
}
#[tokio::test]
async fn test_backup_fixed_database() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/fixed/subscriptions/123/databases/456/backup"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(202).set_body_json(json!({
"taskId": "task-backup-fixed-db",
"commandType": "BACKUP_FIXED_DATABASE",
"status": "processing"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let request = redis_cloud::fixed_databases::FixedDatabaseBackupRequest {
subscription_id: None,
database_id: None,
adhoc_backup_path: None,
command_type: None,
};
let result = handler.backup(123, 456, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-backup-fixed-db".to_string()));
}
#[tokio::test]
async fn test_import_fixed_database() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/fixed/subscriptions/123/databases/456/import"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(202).set_body_json(json!({
"taskId": "task-import-fixed-db",
"commandType": "IMPORT_FIXED_DATABASE",
"status": "processing",
"description": "Importing data into fixed database"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let request = redis_cloud::fixed_databases::FixedDatabaseImportRequest {
source_type: "s3".to_string(),
import_from_uri: vec!["s3://my-bucket/backup.rdb".to_string()],
subscription_id: None,
database_id: None,
command_type: None,
};
let result = handler.import(123, 456, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-import-fixed-db".to_string()));
}
#[tokio::test]
async fn test_tag_operations() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/fixed/subscriptions/123/databases/456/tags"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(202).set_body_json(json!({
"key": "environment",
"value": "production"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let request = redis_cloud::fixed_databases::DatabaseTagCreateRequest {
key: "environment".to_string(),
value: "production".to_string(),
subscription_id: None,
database_id: None,
command_type: None,
};
let result = handler.create_tag(123, 456, &request).await.unwrap();
assert!(result.key.is_some());
}
#[tokio::test]
async fn test_error_handling_401() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/fixed/subscriptions/123/databases"))
.respond_with(ResponseTemplate::new(401).set_body_json(json!({
"error": "Invalid API credentials"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("wrong-key".to_string())
.api_secret("wrong-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let result = handler.list(123, None, None).await;
assert!(result.is_err());
match result {
Err(redis_cloud::CloudError::AuthenticationFailed { .. }) => {}
_ => panic!("Expected AuthenticationFailed error"),
}
}
#[tokio::test]
async fn test_error_handling_403() {
let mock_server = MockServer::start().await;
Mock::given(method("DELETE"))
.and(path("/fixed/subscriptions/123/databases/456"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(403).set_body_json(json!({
"error": "Forbidden: Insufficient permissions"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let result = handler.delete_by_id(123, 456).await;
assert!(result.is_err());
match result {
Err(redis_cloud::CloudError::Forbidden { .. }) => {}
_ => panic!("Expected Forbidden error"),
}
}
#[tokio::test]
async fn test_error_handling_404() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/fixed/subscriptions/999/databases/999"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(404).set_body_json(json!({
"error": "Database not found"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let result = handler.get_by_id(999, 999).await;
assert!(result.is_err());
if let Err(redis_cloud::CloudError::NotFound { message }) = result {
assert!(message.contains("not found") || message.contains("404"));
} else {
panic!("Expected NotFound error");
}
}
#[tokio::test]
async fn test_error_handling_500() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/fixed/subscriptions/123/databases"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(500).set_body_json(json!({
"error": "Internal server error"
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let request = redis_cloud::fixed_databases::FixedDatabaseCreateRequest {
name: "test-database".to_string(),
subscription_id: None,
protocol: None,
memory_limit_in_gb: None,
dataset_size_in_gb: None,
support_oss_cluster_api: None,
redis_version: None,
resp_version: None,
use_external_endpoint_for_oss_cluster_api: None,
enable_database_clustering: None,
number_of_shards: None,
data_persistence: None,
data_eviction_policy: None,
replication: None,
periodic_backup_path: None,
source_ips: None,
regex_rules: None,
replica_of: None,
replica: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
password: None,
alerts: None,
modules: None,
command_type: None,
};
let result = handler.create(123, &request).await;
assert!(result.is_err());
match result {
Err(redis_cloud::CloudError::InternalServerError { .. }) => {}
_ => panic!("Expected InternalServerError error"),
}
}
#[tokio::test]
async fn test_get_fixed_database_traffic() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/fixed/subscriptions/123/databases/456/traffic"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"bdbId": 456,
"trafficStatus": "active",
"canResume": false,
"resumeInProgress": false
})))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
let result = handler.get_traffic(123, 456).await.unwrap();
assert_eq!(result.bdb_id, Some(456));
assert_eq!(result.traffic_status.as_deref(), Some("active"));
assert_eq!(result.can_resume, Some(false));
}
#[tokio::test]
async fn test_resume_fixed_database_traffic() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path(
"/fixed/subscriptions/123/databases/456/traffic/resume",
))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(204))
.mount(&mock_server)
.await;
let client = CloudClient::builder()
.api_key("test-key".to_string())
.api_secret("test-secret".to_string())
.base_url(mock_server.uri())
.build()
.unwrap();
let handler = FixedDatabaseHandler::new(client);
handler.resume_traffic(123, 456).await.unwrap();
}