#![expect(clippy::unwrap_used)]
use wiremock::matchers::{method, path, query_param};
use wiremock::{Mock, ResponseTemplate};
use crate::cli::GroupAction;
use crate::test_helpers::setup_test_env;
use crate::types::OutputFormat;
#[tokio::test]
async fn group_view_returns_info() {
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("GET"))
.and(path("/rest/group"))
.and(query_param("names", "admin"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"groups": [{
"id": 1,
"name": "admin",
"description": "Admin group",
"is_active": true,
"membership": []
}]
})))
.mount(&mock)
.await;
let action = GroupAction::View {
group: "admin".to_string(),
};
let mut __io_a1 = crate::test_helpers::CapturedIo::new();
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __io_a1.writers(),
)
.await;
let output = __io_a1.out_str().to_string();
assert!(result.is_ok(), "group_view failed: {result:?}");
let parsed: serde_json::Value =
serde_json::from_str::<serde_json::Value>(output.trim()).unwrap();
assert_eq!(parsed["id"], 1);
assert_eq!(parsed["name"], "admin");
assert_eq!(parsed["description"], "Admin group");
}
#[tokio::test]
async fn group_create_sends_post() {
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("POST"))
.and(path("/rest/group"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({"id": 5})))
.expect(1)
.mount(&mock)
.await;
let action = GroupAction::Create {
name: "new-group".into(),
description: "A test group".into(),
is_active: true,
};
let mut __io_a2 = crate::test_helpers::CapturedIo::new();
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __io_a2.writers(),
)
.await;
let output = __io_a2.out_str().to_string();
assert!(result.is_ok(), "group create failed: {result:?}");
let parsed: serde_json::Value =
serde_json::from_str::<serde_json::Value>(output.trim()).unwrap();
assert_eq!(parsed["action"], "created");
assert_eq!(parsed["id"], 5);
}
#[tokio::test]
async fn group_update_sends_put() {
let mut __cap_io = crate::test_helpers::CapturedIo::new();
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("PUT"))
.and(path("/rest/group/admin"))
.respond_with(
ResponseTemplate::new(200)
.set_body_json(serde_json::json!({"groups": [{"changes": {}}]})),
)
.expect(1)
.mount(&mock)
.await;
let action = GroupAction::Update {
group: "admin".into(),
description: Some("Updated description".into()),
is_active: None,
};
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __cap_io.writers(),
)
.await;
assert!(result.is_ok(), "group update failed: {result:?}");
}
#[tokio::test]
async fn group_add_user_sends_put() {
let mut __cap_io = crate::test_helpers::CapturedIo::new();
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("PUT"))
.and(path("/rest/user/alice%40test%2Ecom"))
.respond_with(
ResponseTemplate::new(200)
.set_body_json(serde_json::json!({"users": [{"id": 1, "changes": {}}]})),
)
.expect(1)
.mount(&mock)
.await;
let action = GroupAction::AddUser {
group: "admin".into(),
user: "alice@test.com".into(),
};
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __cap_io.writers(),
)
.await;
assert!(result.is_ok(), "group add_user failed: {result:?}");
}
#[tokio::test]
async fn group_remove_user_sends_put() {
let mut __cap_io = crate::test_helpers::CapturedIo::new();
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("PUT"))
.and(path("/rest/user/bob%40test%2Ecom"))
.respond_with(
ResponseTemplate::new(200)
.set_body_json(serde_json::json!({"users": [{"id": 2, "changes": {}}]})),
)
.expect(1)
.mount(&mock)
.await;
let action = GroupAction::RemoveUser {
group: "admin".into(),
user: "bob@test.com".into(),
};
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __cap_io.writers(),
)
.await;
assert!(result.is_ok(), "group remove_user failed: {result:?}");
}
#[tokio::test]
async fn group_list_users_returns_members() {
let mut __cap_io = crate::test_helpers::CapturedIo::new();
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("GET"))
.and(path("/rest/user"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"users": [
{"id": 10, "name": "alice@test.com", "real_name": "Alice", "email": "alice@test.com"},
{"id": 11, "name": "bob@test.com", "real_name": "Bob", "email": "bob@test.com"}
]
})))
.mount(&mock)
.await;
let action = GroupAction::ListUsers {
group: "admin".to_string(),
details: false,
};
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __cap_io.writers(),
)
.await;
assert!(result.is_ok(), "group list_users failed: {result:?}");
}
#[tokio::test]
async fn group_list_users_with_details() {
let mut __cap_io = crate::test_helpers::CapturedIo::new();
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("GET"))
.and(path("/rest/user"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"users": [
{"id": 10, "name": "alice@test.com", "real_name": "Alice", "email": "alice@test.com", "can_login": true}
]
})))
.mount(&mock)
.await;
let action = GroupAction::ListUsers {
group: "admin".to_string(),
details: true,
};
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __cap_io.writers(),
)
.await;
assert!(
result.is_ok(),
"group list_users --details failed: {result:?}"
);
}
#[tokio::test]
async fn group_view_http_500_returns_error() {
let mut __cap_io = crate::test_helpers::CapturedIo::new();
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("GET"))
.and(path("/rest/group"))
.respond_with(ResponseTemplate::new(500).set_body_string("Internal Server Error"))
.mount(&mock)
.await;
let action = GroupAction::View {
group: "admin".to_string(),
};
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __cap_io.writers(),
)
.await;
assert!(result.is_err());
let err = result.unwrap_err().to_string();
assert!(
err.contains("500") || err.contains("Internal Server Error"),
"expected HTTP 500 error, got: {err}"
);
}
#[tokio::test]
async fn group_view_malformed_json_returns_error() {
let mut __cap_io = crate::test_helpers::CapturedIo::new();
let (_lock, mock, _tmp) = setup_test_env().await;
Mock::given(method("POST"))
.and(path("/rest/group"))
.respond_with(ResponseTemplate::new(200).set_body_string("not json"))
.mount(&mock)
.await;
let action = GroupAction::View {
group: "admin".to_string(),
};
let result = super::execute(
&action,
None,
OutputFormat::Json,
None,
&mut __cap_io.writers(),
)
.await;
assert!(result.is_err());
}