use application::sidecar::hash_helper::hash_structured_data; use application::sidecar::{DetectExternalChangesCommand, DetectExternalChangesHandler}; use application::testing::{InMemorySidecarRepository, InMemorySidecarWriter}; use domain::entities::{SidecarRecord, SyncStatus}; use domain::ports::{SidecarRepository, SidecarWriterPort}; use domain::value_objects::{MetadataValue, StructuredData, SystemId}; use std::sync::Arc; #[tokio::test] async fn detects_changed_sidecar() { let sidecar_repo = Arc::new(InMemorySidecarRepository::new()); let writer = Arc::new(InMemorySidecarWriter::new()); let asset_id = SystemId::new(); let path = format!("sidecars/{}.xmp", asset_id); // Write original data and create InSync record with its hash let mut original = StructuredData::new(); original.insert("title", MetadataValue::String("Old".into())); let hash = hash_structured_data(&original); let mut record = SidecarRecord::new(asset_id, &path); record.mark_synced(hash); sidecar_repo.save(&record).await.unwrap(); // Simulate external edit: write different data to sidecar file let mut modified = StructuredData::new(); modified.insert("title", MetadataValue::String("New".into())); writer.write_sidecar(&modified, &path).await.unwrap(); let handler = DetectExternalChangesHandler::new(sidecar_repo.clone(), writer); let changed = handler.execute(DetectExternalChangesCommand).await.unwrap(); assert_eq!(changed, 1); let updated = sidecar_repo .find_by_asset(&asset_id) .await .unwrap() .unwrap(); assert_eq!(updated.sync_status, SyncStatus::PendingRead); } #[tokio::test] async fn ignores_unchanged_sidecar() { let sidecar_repo = Arc::new(InMemorySidecarRepository::new()); let writer = Arc::new(InMemorySidecarWriter::new()); let asset_id = SystemId::new(); let path = format!("sidecars/{}.xmp", asset_id); let mut data = StructuredData::new(); data.insert("title", MetadataValue::String("Same".into())); let hash = hash_structured_data(&data); let mut record = SidecarRecord::new(asset_id, &path); record.mark_synced(hash); sidecar_repo.save(&record).await.unwrap(); // Write identical data to sidecar file writer.write_sidecar(&data, &path).await.unwrap(); let handler = DetectExternalChangesHandler::new(sidecar_repo.clone(), writer); let changed = handler.execute(DetectExternalChangesCommand).await.unwrap(); assert_eq!(changed, 0); let updated = sidecar_repo .find_by_asset(&asset_id) .await .unwrap() .unwrap(); assert_eq!(updated.sync_status, SyncStatus::InSync); }