use application::catalog::{RegisterAssetCommand, RegisterAssetHandler}; use application::testing::{ InMemoryAssetRepository, InMemoryDuplicateRepository, StubEventPublisher, }; use domain::catalog::entities::AssetType; use domain::value_objects::SystemId; use std::sync::Arc; fn valid_checksum() -> String { "a".repeat(64) } #[tokio::test] async fn registers_asset() { let asset_repo = Arc::new(InMemoryAssetRepository::new()); let dup_repo = Arc::new(InMemoryDuplicateRepository::new()); let events = Arc::new(StubEventPublisher::new()); let handler = RegisterAssetHandler::new(asset_repo.clone(), dup_repo.clone(), events.clone()); let owner = SystemId::new(); let volume = SystemId::new(); let (asset, dup) = handler .execute(RegisterAssetCommand { volume_id: volume, relative_path: "photos/img.jpg".into(), checksum: valid_checksum(), asset_type: AssetType::Image, mime_type: "image/jpeg".into(), file_size: 1024, owner_id: owner, }) .await .unwrap(); assert_eq!(asset.mime_type, "image/jpeg"); assert_eq!(asset.file_size, 1024); assert_eq!(asset.owner_user_id, owner); assert!(dup.is_none()); assert_eq!(events.published().await.len(), 1); } #[tokio::test] async fn flags_duplicate_when_checksum_exists() { let asset_repo = Arc::new(InMemoryAssetRepository::new()); let dup_repo = Arc::new(InMemoryDuplicateRepository::new()); let events = Arc::new(StubEventPublisher::new()); let handler = RegisterAssetHandler::new(asset_repo.clone(), dup_repo.clone(), events.clone()); let owner = SystemId::new(); let volume = SystemId::new(); let checksum = valid_checksum(); // First asset let (first, _) = handler .execute(RegisterAssetCommand { volume_id: volume, relative_path: "photos/img1.jpg".into(), checksum: checksum.clone(), asset_type: AssetType::Image, mime_type: "image/jpeg".into(), file_size: 1024, owner_id: owner, }) .await .unwrap(); // Second asset with same checksum let (second, dup) = handler .execute(RegisterAssetCommand { volume_id: volume, relative_path: "photos/img2.jpg".into(), checksum, asset_type: AssetType::Image, mime_type: "image/jpeg".into(), file_size: 1024, owner_id: owner, }) .await .unwrap(); let group = dup.expect("should flag duplicate"); let candidate_ids: Vec<_> = group.candidates.iter().map(|c| c.asset_id).collect(); assert!(candidate_ids.contains(&first.asset_id)); assert!(candidate_ids.contains(&second.asset_id)); }