#![expect(clippy::unwrap_used)]
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
use crate::client::test_helpers::test_client;
use crate::error::BzrError;
use crate::field_aliases::resolve_field_alias;
#[test]
fn resolve_field_alias_maps_status() {
assert_eq!(resolve_field_alias("status").as_ref(), "bug_status");
}
#[test]
fn resolve_field_alias_maps_severity() {
assert_eq!(resolve_field_alias("severity").as_ref(), "bug_severity");
}
#[test]
fn resolve_field_alias_maps_id() {
assert_eq!(resolve_field_alias("id").as_ref(), "bug_id");
}
#[test]
fn resolve_field_alias_maps_type() {
assert_eq!(resolve_field_alias("type").as_ref(), "bug_type");
}
#[test]
fn resolve_field_alias_maps_group() {
assert_eq!(resolve_field_alias("group").as_ref(), "bug_group");
}
#[test]
fn resolve_field_alias_maps_file_loc() {
assert_eq!(resolve_field_alias("file_loc").as_ref(), "bug_file_loc");
}
#[test]
fn resolve_field_alias_passes_through_unknown() {
assert_eq!(resolve_field_alias("priority").as_ref(), "priority");
}
#[test]
fn resolve_field_alias_passes_through_already_prefixed() {
assert_eq!(resolve_field_alias("bug_status").as_ref(), "bug_status");
}
#[test]
fn resolve_field_alias_is_case_insensitive() {
assert_eq!(resolve_field_alias("Status").as_ref(), "bug_status");
assert_eq!(resolve_field_alias("SEVERITY").as_ref(), "bug_severity");
}
#[tokio::test]
async fn get_field_values_returns_values() {
let mock = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/rest/field/bug/bug_status"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"fields": [{
"values": [
{"name": "NEW", "sort_key": 100, "is_active": true, "can_change_to": [{"name": "ASSIGNED"}, {"name": "RESOLVED"}]},
{"name": "RESOLVED", "sort_key": 500, "is_active": true}
]
}]
})))
.mount(&mock)
.await;
let client = test_client(&mock.uri());
let values = client.get_field_values("status").await.unwrap();
assert_eq!(values.len(), 2);
assert_eq!(values[0].name, "NEW");
let transitions = values[0].can_change_to.as_ref().unwrap();
assert_eq!(transitions.len(), 2);
assert_eq!(transitions[0].name, "ASSIGNED");
}
#[tokio::test]
async fn get_field_values_resolves_severity_alias() {
let mock = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/rest/field/bug/bug_severity"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"fields": [{
"values": [
{"name": "blocker", "sort_key": 100, "is_active": true},
{"name": "normal", "sort_key": 200, "is_active": true}
]
}]
})))
.mount(&mock)
.await;
let client = test_client(&mock.uri());
let values = client.get_field_values("severity").await.unwrap();
assert_eq!(values.len(), 2);
assert_eq!(values[0].name, "blocker");
}
#[tokio::test]
async fn get_field_values_unrecognized_field_returns_not_found() {
let mock = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/rest/field/bug/nonexistent"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({"fields": []})))
.mount(&mock)
.await;
let client = test_client(&mock.uri());
let err = client.get_field_values("nonexistent").await.unwrap_err();
assert!(
matches!(
err,
BzrError::NotFound {
resource: "field",
..
}
),
"expected NotFound, got: {err}"
);
}