use domain::entities::{BatchStatus, Job, JobBatch, JobStatus, JobType, ProcessingPipeline}; use domain::errors::DomainError; use domain::value_objects::{StructuredData, SystemId}; // --- Job --- #[test] fn job_lifecycle_success() { let mut job = Job::new(JobType::ExtractMetadata, 5, StructuredData::new()); assert_eq!(job.status, JobStatus::Queued); job.start().unwrap(); assert_eq!(job.status, JobStatus::Processing); assert!(job.started_at.is_some()); job.complete(StructuredData::new()); assert_eq!(job.status, JobStatus::Completed); assert!(job.result_data.is_some()); assert!(job.completed_at.is_some()); } #[test] fn retry_on_failure() { let mut job = Job::new(JobType::ScanDirectory, 1, StructuredData::new()); job.start().unwrap(); job.fail("timeout"); assert_eq!(job.status, JobStatus::Queued); assert_eq!(job.retry_count, 1); assert!(job.can_retry()); assert!(job.started_at.is_none()); } #[test] fn fails_after_max_retries() { let mut job = Job::new(JobType::ScanDirectory, 1, StructuredData::new()); job.max_retries = 2; job.start().unwrap(); job.fail("err1"); assert_eq!(job.status, JobStatus::Queued); job.start().unwrap(); job.fail("err2"); assert_eq!(job.status, JobStatus::Failed); assert!(!job.can_retry()); } #[test] fn cannot_start_from_processing() { let mut job = Job::new(JobType::ScanDirectory, 1, StructuredData::new()); job.start().unwrap(); let result = job.start(); assert!(matches!(result, Err(DomainError::Conflict(_)))); } // --- JobBatch --- #[test] fn completes_when_all_done() { let mut batch = JobBatch::new("scan", 3); batch.record_completion(); batch.record_completion(); batch.record_completion(); assert_eq!(batch.status, BatchStatus::Completed); } #[test] fn completes_with_errors() { let mut batch = JobBatch::new("scan", 3); batch.record_completion(); batch.record_failure(); batch.record_completion(); assert_eq!(batch.status, BatchStatus::CompletedWithErrors); } #[test] fn progress_tracking() { let mut batch = JobBatch::new("scan", 4); assert_eq!(batch.progress_percent(), 0.0); batch.record_completion(); assert_eq!(batch.progress_percent(), 25.0); batch.record_completion(); assert_eq!(batch.progress_percent(), 50.0); } // --- ProcessingPipeline --- #[test] fn steps_ordered() { let mut pipeline = ProcessingPipeline::new("asset.created"); assert!(pipeline.steps.is_empty()); pipeline.add_step(SystemId::new(), StructuredData::new()); pipeline.add_step(SystemId::new(), StructuredData::new()); pipeline.add_step(SystemId::new(), StructuredData::new()); assert_eq!(pipeline.steps.len(), 3); assert_eq!(pipeline.steps[0].step_order, 0); assert_eq!(pipeline.steps[1].step_order, 1); assert_eq!(pipeline.steps[2].step_order, 2); }