use super::super::confirmed_response_result;
use crate::tsm::TsmResponse;
use bacnet_encoding::apdu::{Apdu, decode_apdu};
use bacnet_types::constructed::BACnetObjectPropertyReference;
use bacnet_types::enums::{ErrorClass, ErrorCode, ObjectType, PropertyIdentifier};
use bacnet_types::error::{Error, ErrorDetail, RemoteError};
use bacnet_types::primitives::ObjectIdentifier;
use bytes::Bytes;
#[test]
fn wpm_error_projection_exposes_the_first_failed_write_attempt() {
let wire = [
0x50, 7, 16, 0x0E, 0x91, 2, 0x91, 40, 0x0F, 0x1E, 0x0C, 0x00, 0x80, 0x00, 0x01, 0x19, 85,
0x29, 3, 0x1F,
];
let Apdu::Error(pdu) = decode_apdu(Bytes::copy_from_slice(&wire)).unwrap() else {
panic!("expected an Error PDU");
};
let result = confirmed_response_result(TsmResponse::from_error_pdu(&pdu));
let expected = BACnetObjectPropertyReference {
object_identifier: ObjectIdentifier::new(ObjectType::ANALOG_VALUE, 1).unwrap(),
property_identifier: PropertyIdentifier::PRESENT_VALUE.to_raw(),
property_array_index: Some(3),
};
assert!(
matches!(
&result,
Err(Error::Structured { class: ErrorClass::PROPERTY, code: ErrorCode::WRITE_ACCESS_DENIED, detail })
if **detail == ErrorDetail::FirstFailedWriteAttempt(expected.clone())
),
"{result:?}"
);
}
#[test]
fn plain_error_projection_stays_class_and_code() {
let result = confirmed_response_result(TsmResponse::remote(RemoteError::Error {
class: ErrorClass::PROPERTY,
code: ErrorCode::WRITE_ACCESS_DENIED,
}));
assert!(matches!(
result,
Err(Error::Remote(RemoteError::Error { class, code }))
if class == ErrorClass::PROPERTY
&& code == ErrorCode::WRITE_ACCESS_DENIED
));
}