use ddex_builder::builder::{
BuildRequest, LocalizedStringRequest, MessageHeaderRequest, PartyRequest, ReleaseRequest,
TrackRequest,
};
use ddex_builder::linker::{LinkingError, ReferenceStyle};
use ddex_builder::{EntityType, LinkerConfig, ReferenceLinker};
#[test]
fn test_reference_generator_sequential() {
let mut linker = ReferenceLinker::new();
let resource_ref1 = linker.generate_reference(EntityType::Resource);
let resource_ref2 = linker.generate_reference(EntityType::Resource);
let release_ref1 = linker.generate_reference(EntityType::Release);
let resource_ref3 = linker.generate_reference(EntityType::Resource);
let release_ref2 = linker.generate_reference(EntityType::Release);
let party_ref1 = linker.generate_reference(EntityType::Party);
assert_eq!(resource_ref1, "A1");
assert_eq!(resource_ref2, "A2");
assert_eq!(resource_ref3, "A3");
assert_eq!(release_ref1, "R1");
assert_eq!(release_ref2, "R2");
assert_eq!(party_ref1, "P1");
}
#[test]
fn test_reference_generator_deterministic() {
let mut linker1 = ReferenceLinker::new();
let mut linker2 = ReferenceLinker::new();
let refs1: Vec<String> = (0..10)
.map(|i| {
if i % 2 == 0 {
linker1.generate_reference(EntityType::Resource)
} else {
linker1.generate_reference(EntityType::Release)
}
})
.collect();
let refs2: Vec<String> = (0..10)
.map(|i| {
if i % 2 == 0 {
linker2.generate_reference(EntityType::Resource)
} else {
linker2.generate_reference(EntityType::Release)
}
})
.collect();
assert_eq!(refs1, refs2);
}
#[test]
fn test_entity_registration() {
let mut linker = ReferenceLinker::new();
linker.register_entity(
EntityType::Resource,
"track_001".to_string(),
"A1".to_string(),
);
linker.register_entity(
EntityType::Resource,
"track_002".to_string(),
"A2".to_string(),
);
linker.register_entity(
EntityType::Release,
"release_001".to_string(),
"R1".to_string(),
);
let all_refs = linker.get_all_references();
assert_eq!(all_refs[&EntityType::Resource].len(), 2);
assert_eq!(all_refs[&EntityType::Release].len(), 1);
assert_eq!(all_refs[&EntityType::Resource]["track_001"], "A1");
assert_eq!(all_refs[&EntityType::Resource]["track_002"], "A2");
assert_eq!(all_refs[&EntityType::Release]["release_001"], "R1");
}
#[test]
fn test_release_resource_linking() {
let mut linker = ReferenceLinker::new();
linker.register_entity(
EntityType::Resource,
"track_001".to_string(),
"A1".to_string(),
);
linker.register_entity(
EntityType::Resource,
"track_002".to_string(),
"A2".to_string(),
);
linker.register_entity(
EntityType::Resource,
"track_003".to_string(),
"A3".to_string(),
);
let resource_ids = vec![
"track_001".to_string(),
"track_002".to_string(),
"track_003".to_string(),
];
let references = linker
.link_release_to_resources("release_001", &resource_ids)
.unwrap();
assert_eq!(references.len(), 3);
assert_eq!(references[0].resource_reference, "A1");
assert_eq!(references[0].sequence_number, 1);
assert_eq!(references[1].resource_reference, "A2");
assert_eq!(references[1].sequence_number, 2);
assert_eq!(references[2].resource_reference, "A3");
assert_eq!(references[2].sequence_number, 3);
}
#[test]
fn test_link_unknown_resource_error() {
let mut linker = ReferenceLinker::new();
let resource_ids = vec!["unknown_track".to_string()];
let result = linker.link_release_to_resources("release_001", &resource_ids);
assert!(result.is_err());
match result.unwrap_err() {
LinkingError::UnknownResource(id) => assert_eq!(id, "unknown_track"),
_ => panic!("Expected UnknownResource error"),
}
}
#[test]
fn test_auto_linking_complete_request() {
let mut linker = ReferenceLinker::new();
let mut request = create_test_build_request();
let report = linker.auto_link_request(&mut request).unwrap();
assert!(report.generated_refs > 0);
assert!(report.linked_resources > 0);
assert!(report.validation_passed);
let release = &request.releases[0];
assert!(release.release_reference.is_some());
assert_eq!(release.release_reference.as_ref().unwrap(), "R1");
assert!(release.tracks[0].resource_reference.is_some());
assert_eq!(release.tracks[0].resource_reference.as_ref().unwrap(), "A1");
assert!(release.tracks[1].resource_reference.is_some());
assert_eq!(release.tracks[1].resource_reference.as_ref().unwrap(), "A2");
assert!(release.resource_references.is_some());
let resource_refs = release.resource_references.as_ref().unwrap();
assert_eq!(resource_refs.len(), 2);
assert!(resource_refs.contains(&"A1".to_string()));
assert!(resource_refs.contains(&"A2".to_string()));
assert!(request.header.message_sender.party_reference.is_some());
assert_eq!(
request
.header
.message_sender
.party_reference
.as_ref()
.unwrap(),
"P1"
);
assert!(request.header.message_recipient.party_reference.is_some());
assert_eq!(
request
.header
.message_recipient
.party_reference
.as_ref()
.unwrap(),
"P2"
);
}
#[test]
fn test_validation_passes_with_valid_references() {
let mut linker = ReferenceLinker::new();
linker.register_entity(
EntityType::Resource,
"track_001".to_string(),
"A1".to_string(),
);
linker.register_entity(
EntityType::Release,
"release_001".to_string(),
"R1".to_string(),
);
let validation_result = linker.validate_references();
assert!(validation_result.is_ok());
}
#[test]
fn test_custom_reference_style() {
let config = LinkerConfig {
reference_style: ReferenceStyle::Prefixed {
separator: "_".to_string(),
},
auto_link: true,
validate_on_build: true,
strict: false,
};
let mut linker = ReferenceLinker::with_config(config);
let ref1 = linker.generate_reference(EntityType::Resource);
let ref2 = linker.generate_reference(EntityType::Release);
assert_eq!(ref1, "A_1");
assert_eq!(ref2, "R_1");
}
fn create_test_build_request() -> BuildRequest {
BuildRequest {
header: MessageHeaderRequest {
message_id: Some("TEST_MSG_123".to_string()),
message_sender: PartyRequest {
party_name: vec![LocalizedStringRequest {
text: "Test Label".to_string(),
language_code: Some("en".to_string()),
}],
party_id: Some("SENDER_001".to_string()),
party_reference: None,
},
message_recipient: PartyRequest {
party_name: vec![LocalizedStringRequest {
text: "Test DSP".to_string(),
language_code: Some("en".to_string()),
}],
party_id: Some("RECIPIENT_001".to_string()),
party_reference: None,
},
message_control_type: Some("LiveMessage".to_string()),
message_created_date_time: None, },
version: "4.3".to_string(),
profile: Some("AudioAlbum".to_string()),
releases: vec![ReleaseRequest {
release_id: "REL_001".to_string(),
release_reference: None,
title: vec![LocalizedStringRequest {
text: "Test Album".to_string(),
language_code: Some("en".to_string()),
}],
artist: "Test Artist".to_string(),
label: None, release_date: None, upc: None, tracks: vec![
TrackRequest {
track_id: "TRACK_001".to_string(),
resource_reference: None,
isrc: "USRC12345678".to_string(),
title: "Track 1".to_string(),
duration: "PT3M30S".to_string(),
artist: "Test Artist".to_string(),
},
TrackRequest {
track_id: "TRACK_002".to_string(),
resource_reference: None,
isrc: "USRC12345679".to_string(),
title: "Track 2".to_string(),
duration: "PT4M15S".to_string(),
artist: "Test Artist".to_string(),
},
],
resource_references: None,
}],
deals: vec![],
extensions: None,
}
}