//! Tests for DID document parsing and conversion use atproto_plc::{Did, DidDocument, PlcState, ServiceEndpoint}; use std::collections::HashMap; #[test] fn test_plc_state_validation() { let mut state = PlcState::new(); // Empty state should fail (no rotation keys) assert!(state.validate().is_err()); // Add rotation key state .rotation_keys .push("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N".to_string()); assert!(state.validate().is_ok()); // Add duplicate rotation key state .rotation_keys .push("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N".to_string()); assert!(state.validate().is_err()); } #[test] fn test_plc_state_too_many_rotation_keys() { let mut state = PlcState::new(); // Add 6 rotation keys (max is 5) for i in 0..6 { state .rotation_keys .push(format!("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6{}", i)); } assert!(state.validate().is_err()); } #[test] fn test_plc_state_too_many_verification_methods() { let mut state = PlcState::new(); state .rotation_keys .push("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N".to_string()); // Add 11 verification methods (max is 10) for i in 0..11 { state.verification_methods.insert( format!("key{}", i), format!("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn{}", i), ); } assert!(state.validate().is_err()); } #[test] fn test_service_endpoint_validation() { let valid = ServiceEndpoint::new( "AtprotoPersonalDataServer".to_string(), "https://pds.example.com".to_string(), ); assert!(valid.validate().is_ok()); let empty_type = ServiceEndpoint::new(String::new(), "https://example.com".to_string()); assert!(empty_type.validate().is_err()); let empty_endpoint = ServiceEndpoint::new("SomeService".to_string(), String::new()); assert!(empty_endpoint.validate().is_err()); } #[test] fn test_did_document_from_plc_state() { let did = Did::parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz").unwrap(); let mut state = PlcState::new(); state .rotation_keys .push("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N".to_string()); state.verification_methods.insert( "atproto".to_string(), "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169".to_string(), ); state .also_known_as .push("at://alice.bsky.social".to_string()); state.services.insert( "atproto_pds".to_string(), ServiceEndpoint::new( "AtprotoPersonalDataServer".to_string(), "https://pds.example.com".to_string(), ), ); let doc = state.to_did_document(&did); assert_eq!(doc.id, did); assert_eq!(doc.verification_method.len(), 1); assert_eq!(doc.also_known_as.len(), 1); assert_eq!(doc.service.len(), 1); assert!(!doc.context.is_empty()); } #[test] fn test_did_document_serialization() { let did = Did::parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz").unwrap(); let mut state = PlcState::new(); state .rotation_keys .push("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N".to_string()); let doc = state.to_did_document(&did); // Serialize to JSON let json = serde_json::to_string_pretty(&doc).unwrap(); assert!(json.contains("\"@context\"")); assert!(json.contains("did:plc:ewvi7nxzyoun6zhxrhs64oiz")); // Deserialize back let deserialized: DidDocument = serde_json::from_str(&json).unwrap(); assert_eq!(doc, deserialized); } #[test] fn test_plc_state_serialization() { let mut state = PlcState::new(); state .rotation_keys .push("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N".to_string()); // Serialize let json = serde_json::to_string(&state).unwrap(); assert!(json.contains("rotationKeys")); // Deserialize let deserialized: PlcState = serde_json::from_str(&json).unwrap(); assert_eq!(state, deserialized); } #[test] fn test_did_document_to_plc_state_conversion() { let did = Did::parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz").unwrap(); let mut original_state = PlcState::new(); original_state .rotation_keys .push("did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N".to_string()); original_state.verification_methods.insert( "atproto".to_string(), "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169".to_string(), ); // Convert to DID document and back let doc = original_state.to_did_document(&did); let converted_state = doc.to_plc_state().unwrap(); // Note: rotation_keys are not stored in DID document, so they won't round-trip assert_eq!( original_state.verification_methods, converted_state.verification_methods ); }