use serde_json::json;
use std::sync::Arc;
use tap_agent::message_packing::KeyManagerPacking;
use tap_agent::{PackOptions, Packable, TapAgent};
use tap_msg::didcomm::PlainMessage;
use tap_node::{NodeConfig, TapNode};
#[tokio::test]
async fn test_receive_plain_message() {
let config = NodeConfig::default();
let node = Arc::new(TapNode::new(config));
let (agent, agent_did) = TapAgent::from_ephemeral_key().await.unwrap();
node.register_agent(Arc::new(agent)).await.unwrap();
let message_value = json!({
"id": "test-plain-123",
"typ": "application/didcomm-plain+json",
"type": "https://example.org/test",
"body": {"content": "Hello World"},
"from": "did:example:sender",
"to": [agent_did],
"created_time": 1234567890
});
let result = node.receive_message(message_value).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_receive_signed_message() {
let config = NodeConfig::default();
let node = Arc::new(TapNode::new(config));
let (sender_agent, sender_did) = TapAgent::from_ephemeral_key().await.unwrap();
let (receiver_agent, receiver_did) = TapAgent::from_ephemeral_key().await.unwrap();
node.register_agent(Arc::new(receiver_agent)).await.unwrap();
let message = PlainMessage {
id: "test-signed-123".to_string(),
typ: "application/didcomm-plain+json".to_string(),
type_: "https://example.org/test".to_string(),
body: json!({"content": "Signed message"}),
from: sender_did.clone(),
to: vec![receiver_did.clone()],
thid: None,
pthid: None,
created_time: Some(1234567890),
expires_time: None,
from_prior: None,
attachments: None,
extra_headers: Default::default(),
};
let sender_multibase = sender_did.strip_prefix("did:key:").unwrap();
let sender_kid = format!("{}#{}", sender_did, sender_multibase);
let pack_options = PackOptions::new().with_sign(&sender_kid);
let signed_message = message
.pack(
sender_agent.key_manager().as_ref() as &dyn KeyManagerPacking,
pack_options,
)
.await
.unwrap();
let jws_value: serde_json::Value = serde_json::from_str(&signed_message).unwrap();
let _result = node.receive_message(jws_value).await;
}
#[tokio::test]
async fn test_receive_encrypted_message() {
let config = NodeConfig::default();
let node = Arc::new(TapNode::new(config));
let (sender_agent, sender_did) = TapAgent::from_ephemeral_key().await.unwrap();
let (receiver_agent, receiver_did) = TapAgent::from_ephemeral_key().await.unwrap();
node.register_agent(Arc::new(receiver_agent)).await.unwrap();
let message = PlainMessage {
id: "test-signed-123".to_string(),
typ: "application/didcomm-plain+json".to_string(),
type_: "https://example.org/test".to_string(),
body: json!({"content": "signed content"}),
from: sender_did.clone(),
to: vec![receiver_did.clone()],
thid: None,
pthid: None,
created_time: Some(1234567890),
expires_time: None,
from_prior: None,
attachments: None,
extra_headers: Default::default(),
};
let sender_multibase = sender_did.strip_prefix("did:key:").unwrap();
let sender_kid = format!("{}#{}", sender_did, sender_multibase);
let pack_options = PackOptions::new().with_sign(&sender_kid);
let signed_message = message
.pack(
sender_agent.key_manager().as_ref() as &dyn KeyManagerPacking,
pack_options,
)
.await
.unwrap();
let jws_value: serde_json::Value = serde_json::from_str(&signed_message).unwrap();
let _result = node.receive_message(jws_value).await;
}
#[tokio::test]
async fn test_receive_signed_message_multiple_recipients() {
let config = NodeConfig::default();
let node = Arc::new(TapNode::new(config));
let (sender_agent, sender_did) = TapAgent::from_ephemeral_key().await.unwrap();
let (receiver1_agent, receiver1_did) = TapAgent::from_ephemeral_key().await.unwrap();
let (receiver2_agent, receiver2_did) = TapAgent::from_ephemeral_key().await.unwrap();
node.register_agent(Arc::new(receiver1_agent))
.await
.unwrap();
node.register_agent(Arc::new(receiver2_agent))
.await
.unwrap();
let message = PlainMessage {
id: "test-multi-signed".to_string(),
typ: "application/didcomm-plain+json".to_string(),
type_: "https://example.org/test".to_string(),
body: json!({"content": "for multiple recipients"}),
from: sender_did.clone(),
to: vec![receiver1_did.clone(), receiver2_did.clone()],
thid: None,
pthid: None,
created_time: Some(1234567890),
expires_time: None,
from_prior: None,
attachments: None,
extra_headers: Default::default(),
};
let sender_multibase = sender_did.strip_prefix("did:key:").unwrap();
let sender_kid = format!("{}#{}", sender_did, sender_multibase);
let pack_options = PackOptions::new().with_sign(&sender_kid);
let signed_message = message
.pack(
sender_agent.key_manager().as_ref() as &dyn KeyManagerPacking,
pack_options,
)
.await
.unwrap();
let jws_value: serde_json::Value = serde_json::from_str(&signed_message).unwrap();
let _result = node.receive_message(jws_value).await;
}
#[tokio::test]
async fn test_receive_message_no_agents() {
let config = NodeConfig::default();
let node = Arc::new(TapNode::new(config));
let message_value = json!({
"id": "test-no-agents",
"typ": "application/didcomm-plain+json",
"type": "https://example.org/test",
"body": {"content": "No agents to handle this"},
"from": "did:example:sender",
"to": ["did:example:nonexistent"],
"created_time": 1234567890
});
let result = node.receive_message(message_value).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_receive_message_invalid_json() {
let config = NodeConfig::default();
let node = Arc::new(TapNode::new(config));
let invalid_value = json!("not a message object");
let result = node.receive_message(invalid_value).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_receive_signed_message_no_matching_agents() {
let config = NodeConfig::default();
let node = Arc::new(TapNode::new(config));
let (sender_agent, sender_did) = TapAgent::from_ephemeral_key().await.unwrap();
let (receiver_agent, receiver_did) = TapAgent::from_ephemeral_key().await.unwrap();
let _ = receiver_agent;
let message = PlainMessage {
id: "test-no-matching".to_string(),
typ: "application/didcomm-plain+json".to_string(),
type_: "https://example.org/test".to_string(),
body: json!({"content": "no one can read this"}),
from: sender_did.clone(),
to: vec![receiver_did.clone()],
thid: None,
pthid: None,
created_time: Some(1234567890),
expires_time: None,
from_prior: None,
attachments: None,
extra_headers: Default::default(),
};
let sender_multibase = sender_did.strip_prefix("did:key:").unwrap();
let sender_kid = format!("{}#{}", sender_did, sender_multibase);
let pack_options = PackOptions::new().with_sign(&sender_kid);
let signed_message = message
.pack(
sender_agent.key_manager().as_ref() as &dyn KeyManagerPacking,
pack_options,
)
.await
.unwrap();
let jws_value: serde_json::Value = serde_json::from_str(&signed_message).unwrap();
let result = node.receive_message(jws_value).await;
let _ = result;
}
#[tokio::test]
async fn test_message_type_detection() {
let config = NodeConfig::default();
let node = Arc::new(TapNode::new(config));
let plain_value = json!({
"id": "plain-test",
"typ": "application/didcomm-plain+json",
"type": "https://example.org/test",
"body": {"content": "plain"},
"from": "did:example:sender",
"to": ["did:example:receiver"]
});
let result = node.receive_message(plain_value).await;
assert!(result.is_ok());
let jws_value = json!({
"payload": "eyJpZCI6InRlc3QifQ",
"signatures": [
{
"protected": "eyJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXNpZ25lZCtqc29uIiwiYWxnIjoiRWREU0EiLCJraWQiOiJkaWQ6a2V5OnRlc3Qja2V5In0",
"signature": "dGVzdA"
}
]
});
let _result = node.receive_message(jws_value).await;
let jwe_value = json!({
"protected": "eyJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0",
"recipients": [
{
"header": {"kid": "did:key:test#key"},
"encrypted_key": "dGVzdA"
}
],
"ciphertext": "dGVzdA",
"tag": "dGVzdA",
"iv": "dGVzdA"
});
let result = node.receive_message(jwe_value).await;
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("No agent could process"));
}