use std::collections::HashMap;
use std::str::FromStr;
use tap_caip::AssetId;
use tap_msg::didcomm::PlainMessage;
use tap_msg::message::tap_message_trait::{Connectable, TapMessageBody};
use tap_msg::message::{Agent, Connect, Party, Payment, Transfer};
#[test]
fn test_fuzz_transfer_deserialization() {
let invalid_json = r#"{
"asset": "not-a-valid-asset",
"originator": {
"id": "not-a-valid-did"
},
"amount": "not-a-number",
"agents": "not-an-array"
}"#;
let result = serde_json::from_str::<Transfer>(invalid_json);
assert!(
result.is_err(),
"Should fail to deserialize invalid Transfer JSON"
);
let malformed_json = r#"{
"asset": "eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"originator": {
"id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
},
"amount": "100.0",
"agents": [
{
"id": "did:key:z6MkpDYxrwJw5WoD1o4YVfthJJgZfxrECpW6Da6QCWagRHLx"
}
],
"metadata": {"key": "value"
}"#;
let result = serde_json::from_str::<Transfer>(malformed_json);
assert!(result.is_err(), "Should fail to deserialize malformed JSON");
}
#[test]
fn test_fuzz_connect_deserialization() {
let invalid_json = r#"{
"agents": "not-an-array",
"constraints": "not-a-valid-constraints-object"
}"#;
let result = serde_json::from_str::<Connect>(invalid_json);
assert!(
result.is_err(),
"Should fail to deserialize invalid Connect JSON"
);
let empty_agents_json = r#"{
"agents": [],
"metadata": {}
}"#;
let result = serde_json::from_str::<Connect>(empty_agents_json);
if let Ok(connect) = result {
assert!(
connect.validate().is_err(),
"Connect with empty agents should fail validation"
);
}
}
#[test]
fn test_fuzz_payment_request_deserialization() {
let invalid_json = r#"{
"amount": "not-a-number",
"merchant": "not-a-valid-participant",
"agents": "not-an-array"
}"#;
let result = serde_json::from_str::<Payment>(invalid_json);
assert!(
result.is_err(),
"Should fail to deserialize invalid Payment JSON"
);
let missing_fields_json = r#"{
"amount": "100.0",
"agents": []
}"#;
let result = serde_json::from_str::<Payment>(missing_fields_json);
assert!(
result.is_err(),
"Should fail to deserialize Payment with missing fields"
);
}
#[test]
fn test_fuzz_message_deserialization() {
let invalid_json = r#"{
"id": 12345,
"type": "not-a-valid-type",
"body": "not-a-valid-body"
}"#;
let result = serde_json::from_str::<PlainMessage>(invalid_json);
assert!(
result.is_err(),
"Should fail to deserialize invalid PlainMessage JSON"
);
let missing_fields_json = r#"{
"body": {}
}"#;
let result = serde_json::from_str::<PlainMessage>(missing_fields_json);
assert!(
result.is_err(),
"Should fail to deserialize PlainMessage with missing fields"
);
}
#[test]
fn test_fuzz_connectable_with_invalid_id() {
let mut transfer = create_test_transfer();
transfer.with_connection("");
assert!(transfer.has_connection());
assert_eq!(transfer.connection_id(), Some(""));
let long_id = "a".repeat(10000);
transfer.with_connection(&long_id);
assert!(transfer.has_connection());
assert_eq!(transfer.connection_id(), Some(long_id.as_str()));
let special_chars = "!@#$%^&*()_+{}|:<>?";
transfer.with_connection(special_chars);
assert!(transfer.has_connection());
assert_eq!(transfer.connection_id(), Some(special_chars));
}
#[test]
fn test_fuzz_tap_message_body_validation() {
let mut transfer = create_test_transfer();
transfer.amount = "".to_string();
assert!(
transfer.validate().is_err(),
"Transfer with empty amount should fail validation"
);
transfer.amount = "-100.0".to_string();
assert!(
transfer.validate().is_err(),
"Transfer with negative amount should fail validation"
);
transfer.amount = "not-a-number".to_string();
assert!(
transfer.validate().is_err(),
"Transfer with non-numeric amount should fail validation"
);
let mut transfer = create_test_transfer();
transfer.originator = Some(Party::new(""));
assert!(
transfer.validate().is_err(),
"Transfer with empty originator ID should fail validation"
);
}
#[test]
fn test_fuzz_didcomm_conversion() {
let transfer = create_test_transfer();
let didcomm_message = transfer
.to_didcomm("did:example:sender")
.expect("Failed to convert to DIDComm");
let mut invalid_message = didcomm_message.clone();
invalid_message.type_ = "invalid-type".to_string();
let result = Transfer::from_didcomm(&invalid_message);
assert!(
result.is_err(),
"Should fail to convert message with invalid type to Transfer"
);
let mut invalid_body_message = didcomm_message.clone();
invalid_body_message.body = serde_json::json!({
"asset": "not-a-valid-asset",
"amount": "not-a-number"
});
let result = Transfer::from_didcomm(&invalid_body_message);
assert!(
result.is_err(),
"Should fail to convert message with invalid body to Transfer"
);
}
fn create_test_transfer() -> Transfer {
let asset =
AssetId::from_str("eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48").unwrap();
let originator = Party::new("did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK");
let beneficiary = Party::new("did:key:z6MkmRsjkKHNrBiVz5mhiqhJVYf9E9mxg3MVGqgqMkRwCJd6");
let agents = vec![Agent::new(
"did:key:z6MkpDYxrwJw5WoD1o4YVfthJJgZfxrECpW6Da6QCWagRHLx",
"agent",
"did:key:z6MkpDYxrwJw5WoD1o4YVfthJJgZfxrECpW6Da6QCWagRHLx",
)];
Transfer {
transaction_id: Some(uuid::Uuid::new_v4().to_string()),
asset,
originator: Some(originator),
beneficiary: Some(beneficiary),
amount: "100.0".to_string(),
agents,
settlement_id: None,
expiry: None,
transaction_value: None,
memo: None,
connection_id: None,
metadata: HashMap::new(),
}
}