use redis_cloud::{CloudClient, DatabaseHandler};
use serde_json::json;
use wiremock::matchers::{body_json, header, method, path, query_param};
use wiremock::{Mock, MockServer, ResponseTemplate};
#[tokio::test]
async fn test_get_subscription_databases() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/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!({
"subscription": [{
"subscriptionId": 123,
"numberOfDatabases": 2,
"databases": [],
"links": []
}],
"links": [
{
"href": "https://api.redislabs.com/v1/subscriptions/123/databases/1",
"rel": "database",
"type": "GET"
}
],
"accountId": 456
})))
.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 = DatabaseHandler::new(client);
let result = handler
.get_subscription_databases(123, None, None)
.await
.unwrap();
assert_eq!(result.account_id, Some(456));
assert!(result.links.is_some());
assert_eq!(result.subscription.len(), 1);
assert_eq!(result.subscription[0].subscription_id, 123);
assert_eq!(result.subscription[0].number_of_databases, Some(2));
}
#[tokio::test]
async fn test_create_database() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/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-db-123",
"commandType": "CREATE_DATABASE",
"status": "processing",
"description": "Creating 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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseCreateRequest {
name: "test-database".to_string(),
memory_limit_in_gb: Some(1.0),
data_eviction_policy: Some("allkeys-lru".to_string()),
replication: Some(false),
subscription_id: None,
dry_run: None,
protocol: None,
port: None,
dataset_size_in_gb: None,
redis_version: None,
resp_version: None,
support_oss_cluster_api: None,
use_external_endpoint_for_oss_cluster_api: None,
data_persistence: None,
replica_of: None,
replica: None,
throughput_measurement: None,
local_throughput_measurement: None,
average_item_size_in_bytes: None,
periodic_backup_path: None,
remote_backup: None,
source_ip: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
password: None,
sasl_username: None,
sasl_password: None,
alerts: None,
modules: None,
sharding_type: None,
query_performance_factor: None,
command_type: None,
};
let result = handler.create_database(123, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-create-db-123".to_string()));
assert_eq!(result.command_type, Some("CREATE_DATABASE".to_string()));
assert_eq!(result.status, Some("processing".to_string()));
}
#[tokio::test]
async fn test_get_database_by_id() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/subscriptions/123/databases/456"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"databaseId": 456,
"name": "test-database",
"status": "active",
"memoryLimitInGb": 2.5,
"dataEvictionPolicy": "allkeys-lru",
"replication": true,
"dataPersistence": "aof-every-1-sec",
"privateEndpoint": "redis-12345.c1.us-east-1.redislabs.com:16379",
"publicEndpoint": "redis-12345-ext.c1.us-east-1.redislabs.com:16379",
"protocol": "redis",
"activated": "2024-01-01T00:00:00Z",
"lastModified": "2024-01-01T12:00:00Z"
})))
.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 = DatabaseHandler::new(client);
let result = handler
.get_subscription_database_by_id(123, 456)
.await
.unwrap();
assert_eq!(result.database_id, 456);
assert_eq!(result.name, Some("test-database".to_string()));
assert_eq!(result.status, Some("active".to_string()));
assert_eq!(
result.private_endpoint,
Some("redis-12345.c1.us-east-1.redislabs.com:16379".to_string())
);
assert_eq!(
result.public_endpoint,
Some("redis-12345-ext.c1.us-east-1.redislabs.com:16379".to_string())
);
assert_eq!(result.memory_limit_in_gb, Some(2.5));
assert_eq!(result.data_eviction_policy, Some("allkeys-lru".to_string()));
assert_eq!(result.replication, Some(true));
assert_eq!(result.data_persistence, Some("aof-every-1-sec".to_string()));
assert_eq!(result.protocol, Some("redis".to_string()));
}
#[tokio::test]
async fn test_update_database() {
let mock_server = MockServer::start().await;
Mock::given(method("PUT"))
.and(path("/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-db-456",
"commandType": "UPDATE_DATABASE",
"status": "processing",
"description": "Updating 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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseUpdateRequest {
subscription_id: None,
database_id: None,
dry_run: None,
name: Some("updated-database".to_string()),
memory_limit_in_gb: Some(4.0),
dataset_size_in_gb: None,
resp_version: None,
throughput_measurement: None,
data_persistence: None,
data_eviction_policy: Some("volatile-lru".to_string()),
replication: None,
regex_rules: None,
replica_of: None,
replica: None,
support_oss_cluster_api: None,
use_external_endpoint_for_oss_cluster_api: None,
password: None,
sasl_username: None,
sasl_password: None,
source_ip: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
enable_default_user: None,
periodic_backup_path: None,
remote_backup: None,
alerts: None,
command_type: None,
query_performance_factor: None,
};
let result = handler.update_database(123, 456, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-update-db-456".to_string()));
assert_eq!(result.command_type, Some("UPDATE_DATABASE".to_string()));
}
#[tokio::test]
async fn test_delete_database_by_id() {
let mock_server = MockServer::start().await;
Mock::given(method("DELETE"))
.and(path("/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-db-456",
"commandType": "DELETE_DATABASE",
"status": "processing",
"description": "Deleting 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 = DatabaseHandler::new(client);
let result = handler.delete_database_by_id(123, 456).await.unwrap();
assert_eq!(result.task_id, Some("task-delete-db-456".to_string()));
assert_eq!(result.command_type, Some("DELETE_DATABASE".to_string()));
}
#[tokio::test]
async fn test_backup_database() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/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-db-456",
"commandType": "BACKUP_DATABASE",
"status": "processing",
"description": "Creating database backup"
})))
.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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseBackupRequest {
subscription_id: None,
database_id: None,
region_name: None,
adhoc_backup_path: None,
command_type: None,
};
let result = handler.backup_database(123, 456, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-backup-db-456".to_string()));
assert_eq!(result.command_type, Some("BACKUP_DATABASE".to_string()));
}
#[tokio::test]
async fn test_import_into_database() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/subscriptions/123/databases/456/import"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.and(body_json(json!({
"sourceType": "ftp",
"importFromUri": ["ftp://example.com/backup.rdb"]
})))
.respond_with(ResponseTemplate::new(202).set_body_json(json!({
"taskId": "task-import-db-456",
"commandType": "IMPORT_DATABASE",
"status": "processing",
"description": "Importing data into 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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseImportRequest {
source_type: "ftp".to_string(),
import_from_uri: vec!["ftp://example.com/backup.rdb".to_string()],
subscription_id: None,
database_id: None,
command_type: None,
};
let result = handler.import_database(123, 456, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-import-db-456".to_string()));
assert_eq!(result.command_type, Some("IMPORT_DATABASE".to_string()));
}
#[tokio::test]
async fn test_get_database_modules() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/subscriptions/123/databases/456/modules"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"modules": [
{
"name": "RediSearch",
"version": "2.8.0",
"semanticVersion": "2.8.0"
},
{
"name": "RedisJSON",
"version": "2.4.0",
"semanticVersion": "2.4.0"
}
]
})))
.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 = DatabaseHandler::new(client);
}
#[tokio::test]
async fn test_upgrade_database_module() {
let mock_server = MockServer::start().await;
Mock::given(method("PUT"))
.and(path("/subscriptions/123/databases/456/modules/upgrade"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.and(body_json(json!({
"modules": ["RediSearch"]
})))
.respond_with(ResponseTemplate::new(202).set_body_json(json!({
"taskId": "task-upgrade-module",
"commandType": "UPGRADE_DATABASE_MODULE",
"status": "processing",
"description": "Upgrading database modules"
})))
.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 = DatabaseHandler::new(client);
let _request = json!({
"modules": ["RediSearch"]
});
}
#[tokio::test]
async fn test_get_database_pricing() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/subscriptions/123/databases/456/pricing"))
.and(query_param("shardType", "standard"))
.and(header("x-api-key", "test-key"))
.and(header("x-api-secret-key", "test-secret"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"pricing": {
"databaseName": "test-database",
"pricePerHour": 0.124,
"pricePerMonth": 89.28,
"region": "us-east-1"
}
})))
.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 = DatabaseHandler::new(client);
}
#[tokio::test]
async fn test_create_database_with_modules() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/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-db-with-modules",
"commandType": "CREATE_DATABASE",
"status": "processing",
"description": "Creating database with modules"
})))
.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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseCreateRequest {
name: "test-database-with-modules".to_string(),
subscription_id: None,
dry_run: None,
protocol: None,
port: None,
memory_limit_in_gb: Some(2.0),
dataset_size_in_gb: None,
redis_version: None,
resp_version: None,
support_oss_cluster_api: None,
use_external_endpoint_for_oss_cluster_api: None,
data_persistence: None,
data_eviction_policy: None,
replication: None,
replica_of: None,
replica: None,
throughput_measurement: None,
local_throughput_measurement: None,
average_item_size_in_bytes: None,
periodic_backup_path: None,
remote_backup: None,
source_ip: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
password: None,
sasl_username: None,
sasl_password: None,
alerts: None,
modules: Some(vec![
redis_cloud::databases::DatabaseModuleSpec {
name: "RediSearch".to_string(),
parameters: None,
},
redis_cloud::databases::DatabaseModuleSpec {
name: "RedisJSON".to_string(),
parameters: None,
},
]),
sharding_type: None,
query_performance_factor: None,
command_type: None,
};
let result = handler.create_database(123, &request).await.unwrap();
assert_eq!(
result.task_id,
Some("task-create-db-with-modules".to_string())
);
assert_eq!(result.command_type, Some("CREATE_DATABASE".to_string()));
}
#[tokio::test]
async fn test_create_database_with_alerts() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/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-db-alerts",
"commandType": "CREATE_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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseCreateRequest {
name: "test-database-with-alerts".to_string(),
subscription_id: None,
dry_run: None,
protocol: None,
port: None,
memory_limit_in_gb: Some(1.0),
dataset_size_in_gb: None,
redis_version: None,
resp_version: None,
support_oss_cluster_api: None,
use_external_endpoint_for_oss_cluster_api: None,
data_persistence: None,
data_eviction_policy: None,
replication: None,
replica_of: None,
replica: None,
throughput_measurement: None,
local_throughput_measurement: None,
average_item_size_in_bytes: None,
periodic_backup_path: None,
remote_backup: None,
source_ip: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
password: None,
sasl_username: None,
sasl_password: None,
alerts: Some(vec![redis_cloud::databases::DatabaseAlertSpec {
name: "dataset-size".to_string(),
value: 80,
}]),
modules: None,
sharding_type: None,
query_performance_factor: None,
command_type: None,
};
let result = handler.create_database(123, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-create-db-alerts".to_string()));
}
#[tokio::test]
async fn test_database_with_clustering() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/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-clustered-db",
"commandType": "CREATE_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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseCreateRequest {
name: "clustered-database".to_string(),
subscription_id: None,
dry_run: None,
protocol: None,
port: None,
memory_limit_in_gb: Some(10.0),
dataset_size_in_gb: None,
redis_version: None,
resp_version: None,
support_oss_cluster_api: None,
use_external_endpoint_for_oss_cluster_api: None,
data_persistence: None,
data_eviction_policy: None,
replication: None,
replica_of: None,
replica: None,
throughput_measurement: None,
local_throughput_measurement: None,
average_item_size_in_bytes: None,
periodic_backup_path: None,
remote_backup: None,
source_ip: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
password: None,
sasl_username: None,
sasl_password: None,
alerts: None,
modules: None,
sharding_type: Some("standard".to_string()),
query_performance_factor: None,
command_type: None,
};
let result = handler.create_database(123, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-create-clustered-db".to_string()));
}
#[tokio::test]
async fn test_task_response_with_error() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/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-failed-create",
"commandType": "CREATE_DATABASE",
"status": "failed",
"description": "Failed to create database",
"response": {
"error": "Insufficient memory quota",
"additionalInfo": "Subscription memory limit exceeded"
}
})))
.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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseCreateRequest {
name: "test-database".to_string(),
subscription_id: None,
dry_run: None,
protocol: None,
port: None,
memory_limit_in_gb: Some(100.0),
dataset_size_in_gb: None,
redis_version: None,
resp_version: None,
support_oss_cluster_api: None,
use_external_endpoint_for_oss_cluster_api: None,
data_persistence: None,
data_eviction_policy: None,
replication: None,
replica_of: None,
replica: None,
throughput_measurement: None,
local_throughput_measurement: None,
average_item_size_in_bytes: None,
periodic_backup_path: None,
remote_backup: None,
source_ip: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
password: None,
sasl_username: None,
sasl_password: None,
alerts: None,
modules: None,
sharding_type: None,
query_performance_factor: None,
command_type: None,
};
let result = handler.create_database(123, &request).await.unwrap();
assert_eq!(result.task_id, Some("task-failed-create".to_string()));
assert_eq!(result.status, Some("failed".to_string()));
assert!(result.response.is_some());
}
#[tokio::test]
async fn test_error_handling_401() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/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 = DatabaseHandler::new(client);
let result = handler.get_subscription_databases(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("/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 = DatabaseHandler::new(client);
let result = handler.delete_database_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("/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 = DatabaseHandler::new(client);
let result = handler.get_subscription_database_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("/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 = DatabaseHandler::new(client);
let request = redis_cloud::databases::DatabaseCreateRequest {
name: "test-database".to_string(),
subscription_id: None,
dry_run: None,
protocol: None,
port: None,
memory_limit_in_gb: None,
dataset_size_in_gb: None,
redis_version: None,
resp_version: None,
support_oss_cluster_api: None,
use_external_endpoint_for_oss_cluster_api: None,
data_persistence: None,
data_eviction_policy: None,
replication: None,
replica_of: None,
replica: None,
throughput_measurement: None,
local_throughput_measurement: None,
average_item_size_in_bytes: None,
periodic_backup_path: None,
remote_backup: None,
source_ip: None,
client_ssl_certificate: None,
client_tls_certificates: None,
enable_tls: None,
password: None,
sasl_username: None,
sasl_password: None,
alerts: None,
modules: None,
sharding_type: None,
query_performance_factor: None,
command_type: None,
};
let result = handler.create_database(123, &request).await;
assert!(result.is_err());
match result {
Err(redis_cloud::CloudError::InternalServerError { .. }) => {}
_ => panic!("Expected InternalServerError error"),
}
}
#[tokio::test]
async fn test_get_all_databases_single_page() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/subscriptions/123/databases"))
.and(query_param("offset", "0"))
.and(query_param("limit", "100"))
.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": 1,
"name": "db-one",
"status": "active"
},
{
"databaseId": 2,
"name": "db-two",
"status": "active"
}
]
}]
})))
.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 = DatabaseHandler::new(client);
let databases = handler.get_all_databases(123).await.unwrap();
assert_eq!(databases.len(), 2);
assert_eq!(databases[0].database_id, 1);
assert_eq!(databases[0].name, Some("db-one".to_string()));
assert_eq!(databases[1].database_id, 2);
assert_eq!(databases[1].name, Some("db-two".to_string()));
}
#[tokio::test]
async fn test_get_all_databases_multiple_pages() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/subscriptions/123/databases"))
.and(query_param("offset", "0"))
.and(query_param("limit", "2"))
.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": 3,
"databases": [
{ "databaseId": 1, "name": "db-one" },
{ "databaseId": 2, "name": "db-two" }
]
}]
})))
.mount(&mock_server)
.await;
Mock::given(method("GET"))
.and(path("/subscriptions/123/databases"))
.and(query_param("offset", "2"))
.and(query_param("limit", "2"))
.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": 3,
"databases": [
{ "databaseId": 3, "name": "db-three" }
]
}]
})))
.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 = DatabaseHandler::new(client);
use futures::StreamExt;
use std::pin::pin;
let mut databases = Vec::new();
let mut stream = pin!(handler.stream_databases_with_page_size(123, 2));
while let Some(result) = stream.next().await {
databases.push(result.unwrap());
}
assert_eq!(databases.len(), 3);
assert_eq!(databases[0].database_id, 1);
assert_eq!(databases[1].database_id, 2);
assert_eq!(databases[2].database_id, 3);
}
#[tokio::test]
async fn test_get_all_databases_empty() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/subscriptions/123/databases"))
.and(query_param("offset", "0"))
.and(query_param("limit", "100"))
.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": 0,
"databases": []
}]
})))
.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 = DatabaseHandler::new(client);
let databases = handler.get_all_databases(123).await.unwrap();
assert!(databases.is_empty());
}
#[tokio::test]
async fn test_stream_databases() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/subscriptions/123/databases"))
.and(query_param("offset", "0"))
.and(query_param("limit", "100"))
.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": 1, "name": "db-one" },
{ "databaseId": 2, "name": "db-two" }
]
}]
})))
.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 = DatabaseHandler::new(client);
use futures::StreamExt;
use std::pin::pin;
let mut stream = pin!(handler.stream_databases(123));
let mut count = 0;
while let Some(result) = stream.next().await {
let db = result.unwrap();
count += 1;
assert!(db.database_id == 1 || db.database_id == 2);
}
assert_eq!(count, 2);
}