use serde_json::json;
use std::collections::HashMap;
use tap_msg::didcomm::PlainMessage;
use tap_msg::message::{Attachment, DIDCommPresentation, TapMessageBody};
#[tokio::test]
async fn test_didcomm_presentation_deserialization() {
let message_json = json!({
"from": "did:web:originator.vasp",
"type": "https://didcomm.org/present-proof/3.0/presentation",
"id": "f1ca8245-ab2d-4d9c-8d7d-94bf310314ef",
"thid": "95e63a5f-73e1-46ac-b269-48bb22591bfa",
"to": ["did:web:beneficiary.vasp"],
"created_time": 1516269022,
"expires_time": 1516385931,
"body": {
"formats": ["dif/presentation-exchange/submission@v1.0"],
"attachments": []
},
"attachments": [
{
"id": "2a3f1c4c-623c-44e6-b159-179048c51260",
"media_type": "application/json",
"format": "dif/presentation-exchange/submission@v1.0",
"data": {
"json": {
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://identity.foundation/presentation-exchange/submission/v1"
],
"type": [
"VerifiablePresentation",
"PresentationSubmission"
],
"presentation_submission": {
"id": "a30e3b91-fb77-4d22-95fa-871689c322e2",
"definition_id": "32f54163-7166-48f1-93d8-ff217bdb0653",
"descriptor_map": [
{
"id": "beneficiary_vp",
"format": "jwt_vc",
"path": "$.verifiableCredential[0]"
}
]
},
"verifiableCredential": [
{
"@context": ["https://www.w3.org/2018/credentials/v1","https://schema.org/Person"],
"type": ["VerifiableCredential", "Person"],
"issuer": "did:web:originator.vasp",
"issuanceDate": "2022-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:eg:bob",
"givenName": "Bob",
"familyName": "Smith"
}
}
]
}
}
}
]
});
let message_str = message_json.to_string();
let message: PlainMessage =
serde_json::from_str(&message_str).expect("Failed to parse message");
let presentation = DIDCommPresentation::from_didcomm(&message)
.expect("Failed to convert to DIDCommPresentation");
assert_eq!(
presentation.thid,
Some("95e63a5f-73e1-46ac-b269-48bb22591bfa".to_string())
);
assert_eq!(presentation.formats.len(), 1);
assert_eq!(
presentation.formats[0],
"dif/presentation-exchange/submission@v1.0"
);
assert_eq!(presentation.attachments.len(), 1);
}
#[tokio::test]
async fn test_didcomm_presentation_validation() {
let presentation = DIDCommPresentation {
id: uuid::Uuid::new_v4().to_string(),
thid: Some("test-thread-id".to_string()),
formats: vec!["dif/presentation-exchange/submission@v1.0".to_string()],
attachments: vec![Attachment {
id: Some("test-attachment-id".to_string()),
media_type: Some("application/json".to_string()),
data: tap_msg::didcomm::AttachmentData::Json {
value: tap_msg::didcomm::JsonAttachmentData {
json: json!({
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": ["VerifiablePresentation"],
"test": "data"
}),
jws: None,
},
},
description: None,
filename: None,
format: Some("dif/presentation-exchange/submission@v1.0".to_string()),
lastmod_time: None,
byte_count: None,
}],
};
assert!(presentation.validate().is_ok());
let invalid_presentation = DIDCommPresentation {
id: uuid::Uuid::new_v4().to_string(),
thid: Some("test-thread-id".to_string()),
formats: vec!["dif/presentation-exchange/submission@v1.0".to_string()],
attachments: vec![],
};
assert!(invalid_presentation.validate().is_err());
let invalid_presentation2 = DIDCommPresentation {
id: uuid::Uuid::new_v4().to_string(),
thid: Some("test-thread-id".to_string()),
formats: vec!["dif/presentation-exchange/submission@v1.0".to_string()],
attachments: vec![Attachment {
id: Some("".to_string()),
media_type: Some("application/json".to_string()),
data: tap_msg::didcomm::AttachmentData::Json {
value: tap_msg::didcomm::JsonAttachmentData {
json: json!({}),
jws: None,
},
},
description: None,
filename: None,
format: Some("dif/presentation-exchange/submission@v1.0".to_string()),
lastmod_time: None,
byte_count: None,
}],
};
assert!(invalid_presentation2.validate().is_err());
}
#[tokio::test]
async fn test_didcomm_presentation_to_didcomm() {
let presentation = DIDCommPresentation {
id: uuid::Uuid::new_v4().to_string(),
thid: Some("test-thread-id".to_string()),
formats: vec!["dif/presentation-exchange/submission@v1.0".to_string()],
attachments: vec![Attachment {
id: Some("test-attachment-id".to_string()),
media_type: Some("application/json".to_string()),
data: tap_msg::didcomm::AttachmentData::Json {
value: tap_msg::didcomm::JsonAttachmentData {
json: json!({
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": ["VerifiablePresentation"],
"test": "data"
}),
jws: None,
},
},
description: None,
filename: None,
format: Some("dif/presentation-exchange/submission@v1.0".to_string()),
lastmod_time: None,
byte_count: None,
}],
};
let message = presentation
.to_didcomm("did:example:sender")
.expect("Failed to convert to DIDComm");
assert_eq!(
message.type_,
"https://didcomm.org/present-proof/3.0/presentation"
);
assert_eq!(message.thid, Some("test-thread-id".to_string()));
let body = message.body.as_object().unwrap();
let formats = body.get("formats").unwrap().as_array().unwrap();
assert_eq!(formats.len(), 1);
assert_eq!(
formats[0].as_str().unwrap(),
"dif/presentation-exchange/submission@v1.0"
);
let presentation_after = DIDCommPresentation::from_didcomm(&message).unwrap();
assert_eq!(presentation_after.attachments.len(), 1);
assert_eq!(
presentation_after.attachments[0].id,
Some("test-attachment-id".to_string())
);
assert_eq!(
presentation_after.attachments[0].media_type,
Some("application/json".to_string())
);
}
#[tokio::test]
async fn test_round_trip_conversion() {
let didcomm_message = PlainMessage {
id: "test-id".to_string(),
typ: "application/didcomm-plain+json".to_string(),
type_: "https://didcomm.org/present-proof/3.0/presentation".to_string(),
body: json!({
"formats": ["dif/presentation-exchange/submission@v1.0"],
"attachments": [],
"metadata": {
"additional": "data"
}
}),
from: "did:example:sender".to_string(),
to: vec!["did:example:recipient".to_string()],
thid: Some("test-thread-id".to_string()),
pthid: None,
created_time: Some(1234567890),
expires_time: None,
from_prior: None,
extra_headers: HashMap::new(),
attachments: Some(vec![Attachment {
id: Some("test-attachment-id".to_string()),
media_type: Some("application/json".to_string()),
data: tap_msg::didcomm::AttachmentData::Json {
value: tap_msg::didcomm::JsonAttachmentData {
json: json!({
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": ["VerifiablePresentation"],
"test": "data"
}),
jws: None,
},
},
description: None,
filename: None,
format: Some("dif/presentation-exchange/submission@v1.0".to_string()),
lastmod_time: None,
byte_count: None,
}]),
};
let mut presentation = DIDCommPresentation::from_didcomm(&didcomm_message).unwrap();
presentation.formats = vec!["dif/presentation-exchange/submission@v1.0".to_string()];
presentation.attachments = vec![Attachment {
id: Some("test-attachment-id".to_string()),
description: None,
filename: None,
media_type: Some("application/json".to_string()),
format: Some("dif/presentation-exchange/submission@v1.0".to_string()),
data: tap_msg::didcomm::AttachmentData::Json {
value: tap_msg::didcomm::JsonAttachmentData {
json: json!({
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": ["VerifiablePresentation"],
"test": "data"
}),
jws: None,
},
},
lastmod_time: None,
byte_count: None,
}];
let presentation = DIDCommPresentation::from_didcomm(&didcomm_message).unwrap();
let round_trip_message = presentation.to_didcomm("did:example:sender").unwrap();
assert_eq!(round_trip_message.type_, didcomm_message.type_);
assert_eq!(round_trip_message.thid, didcomm_message.thid);
let round_trip_body = round_trip_message.body.as_object().unwrap();
let original_body = didcomm_message.body.as_object().unwrap();
assert_eq!(round_trip_body.get("formats"), original_body.get("formats"));
let round_trip_presentation = DIDCommPresentation::from_didcomm(&round_trip_message).unwrap();
assert_eq!(round_trip_presentation.formats, presentation.formats);
assert!(!presentation.attachments.is_empty());
let attachment = &presentation.attachments[0];
assert_eq!(attachment.id, Some("test-attachment-id".to_string()));
assert_eq!(attachment.media_type, Some("application/json".to_string()));
assert_eq!(presentation.thid, round_trip_presentation.thid);
assert_eq!(presentation.formats, round_trip_presentation.formats);
}