Skip to content

Commit aaa65d2

Browse files
fix/services list endpoint (#329)
* fix(enterprise): use correct endpoint for services list command The services list command was using /v1/services which doesn't exist for GET requests. Changed to use /v1/local/services which is the correct documented endpoint. Fixes #322 * test(enterprise): improve mock tests with realistic API responses - Add comprehensive test fixtures with actual API response data - Update tests to use realistic fixtures - Fix User struct: email is primary identifier, not username - Fix License struct: key field is optional, not required license_key - Add explicit deserialization tests for type validation Fixes #326 * fix: resolve CI compilation issues - Add recursion limit to cluster_tests.rs for large JSON fixtures - Fix test assertions to match actual ClusterInfo struct fields - Allow dead code warnings in common test modules - Remove problematic mod.rs that was causing duplicate module errors - Fix integer overflow issues in test fixtures (use i64 suffix)
1 parent 48426c1 commit aaa65d2

File tree

8 files changed

+560
-182
lines changed

8 files changed

+560
-182
lines changed

crates/redis-enterprise/src/license.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use typed_builder::TypedBuilder;
1414
/// License information
1515
#[derive(Debug, Clone, Serialize, Deserialize)]
1616
pub struct License {
17-
/// License key field
17+
/// License key - the actual field name returned by API
1818
#[serde(skip_serializing_if = "Option::is_none")]
1919
pub key: Option<String>,
2020

crates/redis-enterprise/src/users.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use typed_builder::TypedBuilder;
1919
#[derive(Debug, Clone, Serialize, Deserialize)]
2020
pub struct User {
2121
pub uid: u32,
22-
/// User's email address (used as login identifier)
22+
/// User's email address (used as login identifier) - was incorrectly named 'username'
2323
pub email: String,
2424
/// User's display name
2525
pub name: Option<String>,

crates/redis-enterprise/tests/cluster_tests.rs

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! Cluster endpoint tests for Redis Enterprise
2+
#![recursion_limit = "256"]
23

3-
use redis_enterprise::{ClusterHandler, EnterpriseClient};
4+
mod common;
5+
6+
use redis_enterprise::{ClusterHandler, ClusterInfo, EnterpriseClient};
47
use serde_json::json;
58
use wiremock::matchers::{basic_auth, method, path};
69
use wiremock::{Mock, MockServer, ResponseTemplate};
@@ -10,15 +13,6 @@ fn success_response(body: serde_json::Value) -> ResponseTemplate {
1013
ResponseTemplate::new(200).set_body_json(body)
1114
}
1215

13-
fn test_cluster() -> serde_json::Value {
14-
json!({
15-
"name": "test-cluster",
16-
"nodes_count": 3,
17-
"version": "6.4.2-30",
18-
"license": "valid"
19-
})
20-
}
21-
2216
#[tokio::test]
2317
async fn test_cluster_actions_and_auditing() {
2418
let mock_server = MockServer::start().await;
@@ -139,7 +133,7 @@ async fn test_cluster_get() {
139133
Mock::given(method("GET"))
140134
.and(path("/v1/cluster"))
141135
.and(basic_auth("admin", "password"))
142-
.respond_with(success_response(test_cluster()))
136+
.respond_with(success_response(common::fixtures::cluster_info_response()))
143137
.mount(&mock_server)
144138
.await;
145139

@@ -154,8 +148,37 @@ async fn test_cluster_get() {
154148
let result = handler.info().await;
155149

156150
assert!(result.is_ok());
157-
let _cluster = result.unwrap();
158-
// ClusterInfo struct would have these fields available
151+
let cluster = result.unwrap();
152+
// Verify some key fields that had type mismatches
153+
assert_eq!(cluster.name, "test-cluster.local");
154+
assert!(cluster.sentinel_cipher_suites.is_some());
155+
}
156+
157+
#[tokio::test]
158+
async fn test_cluster_info_deserialization() {
159+
// This test explicitly validates that ClusterInfo can deserialize actual API responses
160+
let cluster_json = common::fixtures::cluster_info_response();
161+
162+
// This would panic if deserialization fails with type mismatches
163+
let cluster_info: ClusterInfo = serde_json::from_value(cluster_json.clone()).unwrap();
164+
165+
// Verify fields that previously had type mismatches
166+
assert_eq!(cluster_info.name, "test-cluster.local");
167+
168+
// sentinel_cipher_suites was Option<String> but should be Option<Vec<String>>
169+
assert!(cluster_info.sentinel_cipher_suites.is_some());
170+
if let Some(cipher_suites) = &cluster_info.sentinel_cipher_suites {
171+
assert_eq!(cipher_suites.len(), 0); // Empty array in fixture
172+
}
173+
174+
// password_complexity was Option<Value> but should be Option<bool>
175+
assert_eq!(cluster_info.password_complexity, Some(false));
176+
177+
// mtls_certificate_authentication was Option<String> but should be Option<bool>
178+
assert_eq!(cluster_info.mtls_certificate_authentication, Some(false));
179+
180+
// upgrade_mode was Option<String> but should be Option<bool>
181+
assert_eq!(cluster_info.upgrade_mode, Some(false));
159182
}
160183

161184
#[tokio::test]

0 commit comments

Comments
 (0)