use std::sync::Arc; use application::testing::{InMemoryPipelineRepository, InMemoryPluginRepository}; use application::processing::{ConfigurePipelineCommand, ConfigurePipelineHandler, PipelineStepConfig}; use domain::entities::{Plugin, PluginType}; use domain::errors::DomainError; use domain::ports::PluginRepository; use domain::value_objects::{StructuredData, SystemId}; #[tokio::test] async fn creates_pipeline() { let pipeline_repo = Arc::new(InMemoryPipelineRepository::new()); let plugin_repo = Arc::new(InMemoryPluginRepository::new()); let p1 = Plugin::new("EXIF", PluginType::MediaProcessor); let p2 = Plugin::new("Thumb", PluginType::MediaProcessor); let p1_id = p1.plugin_id; let p2_id = p2.plugin_id; plugin_repo.save(&p1).await.unwrap(); plugin_repo.save(&p2).await.unwrap(); let handler = ConfigurePipelineHandler::new(pipeline_repo.clone(), plugin_repo.clone()); let pipeline = handler.execute(ConfigurePipelineCommand { trigger_event: "asset.ingested".into(), steps: vec![ PipelineStepConfig { plugin_id: p1_id, config: StructuredData::new() }, PipelineStepConfig { plugin_id: p2_id, config: StructuredData::new() }, ], }).await.unwrap(); assert_eq!(pipeline.trigger_event, "asset.ingested"); assert_eq!(pipeline.steps.len(), 2); } #[tokio::test] async fn rejects_nonexistent_plugin() { let pipeline_repo = Arc::new(InMemoryPipelineRepository::new()); let plugin_repo = Arc::new(InMemoryPluginRepository::new()); let handler = ConfigurePipelineHandler::new(pipeline_repo.clone(), plugin_repo.clone()); let result = handler.execute(ConfigurePipelineCommand { trigger_event: "asset.ingested".into(), steps: vec![ PipelineStepConfig { plugin_id: SystemId::new(), config: StructuredData::new() }, ], }).await; assert!(matches!(result, Err(DomainError::NotFound(_)))); }