use super::*;
use brainwires_core::{TaskPriority, TaskStatus};
#[tokio::test]
async fn test_create_task() {
let manager = TaskManager::new();
let id = manager
.create_task("Test task".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let task = manager.get_task(&id).await.unwrap();
assert_eq!(task.description, "Test task");
assert_eq!(task.status, TaskStatus::Pending);
}
#[tokio::test]
async fn test_create_subtask() {
let manager = TaskManager::new();
let parent_id = manager
.create_task("Parent task".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let child_id = manager
.add_subtask(parent_id.clone(), "Child task".to_string())
.await
.unwrap();
let parent = manager.get_task(&parent_id).await.unwrap();
let child = manager.get_task(&child_id).await.unwrap();
assert!(parent.children.contains(&child_id));
assert_eq!(child.parent_id, Some(parent_id));
}
#[tokio::test]
async fn test_task_lifecycle() {
let manager = TaskManager::new();
let id = manager
.create_task("Lifecycle test".to_string(), None, TaskPriority::High)
.await
.unwrap();
manager.start_task(&id).await.unwrap();
let task = manager.get_task(&id).await.unwrap();
assert_eq!(task.status, TaskStatus::InProgress);
manager
.complete_task(&id, "Done!".to_string())
.await
.unwrap();
let task = manager.get_task(&id).await.unwrap();
assert_eq!(task.status, TaskStatus::Completed);
assert_eq!(task.summary, Some("Done!".to_string()));
}
#[tokio::test]
async fn test_dependencies() {
let manager = TaskManager::new();
let task_a = manager
.create_task("Task A".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let task_b = manager
.create_task(
"Task B (depends on A)".to_string(),
None,
TaskPriority::Normal,
)
.await
.unwrap();
manager.add_dependency(&task_b, &task_a).await.unwrap();
let b = manager.get_task(&task_b).await.unwrap();
assert_eq!(b.status, TaskStatus::Blocked);
let ready = manager.get_ready_tasks().await;
assert_eq!(ready.len(), 1);
assert_eq!(ready[0].id, task_a);
}
#[tokio::test]
async fn test_get_stats() {
let manager = TaskManager::new();
let id1 = manager
.create_task("Task 1".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let id2 = manager
.create_task("Task 2".to_string(), None, TaskPriority::High)
.await
.unwrap();
let _id3 = manager
.create_task("Task 3".to_string(), None, TaskPriority::Low)
.await
.unwrap();
manager.start_task(&id1).await.unwrap();
manager
.complete_task(&id2, "Done".to_string())
.await
.unwrap();
let stats = manager.get_stats().await;
assert_eq!(stats.total, 3);
assert_eq!(stats.pending, 1);
assert_eq!(stats.in_progress, 1);
assert_eq!(stats.completed, 1);
}
#[tokio::test]
async fn test_skip_task() {
let manager = TaskManager::new();
let id = manager
.create_task("Skip me".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
manager
.skip_task(&id, Some("Not needed".to_string()))
.await
.unwrap();
let task = manager.get_task(&id).await.unwrap();
assert_eq!(task.status, TaskStatus::Skipped);
assert_eq!(task.summary, Some("Not needed".to_string()));
assert!(task.completed_at.is_some());
}
#[tokio::test]
async fn test_skip_unblocks_dependents() {
let manager = TaskManager::new();
let task_a = manager
.create_task("Task A".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let task_b = manager
.create_task("Task B".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
manager.add_dependency(&task_b, &task_a).await.unwrap();
let b = manager.get_task(&task_b).await.unwrap();
assert_eq!(b.status, TaskStatus::Blocked);
manager.skip_task(&task_a, None).await.unwrap();
let b = manager.get_task(&task_b).await.unwrap();
assert_eq!(b.status, TaskStatus::Pending);
}
#[tokio::test]
async fn test_circular_dependency_detection() {
let manager = TaskManager::new();
let task_a = manager
.create_task("Task A".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let task_b = manager
.create_task("Task B".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
manager.add_dependency(&task_a, &task_b).await.unwrap();
let result = manager.add_dependency(&task_b, &task_a).await;
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("circular"));
}
#[tokio::test]
async fn test_self_dependency_detection() {
let manager = TaskManager::new();
let task_a = manager
.create_task("Task A".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let result = manager.add_dependency(&task_a, &task_a).await;
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("circular"));
}
#[tokio::test]
async fn test_can_start() {
let manager = TaskManager::new();
let task_a = manager
.create_task("Task A".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let task_b = manager
.create_task("Task B".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
manager.add_dependency(&task_b, &task_a).await.unwrap();
assert!(manager.can_start(&task_a).await.is_ok());
assert_eq!(manager.can_start(&task_a).await, Ok(true));
let result = manager.can_start(&task_b).await;
assert!(result.is_err());
assert_eq!(result.unwrap_err(), vec![task_a.clone()]);
manager
.complete_task(&task_a, "Done".to_string())
.await
.unwrap();
assert_eq!(manager.can_start(&task_b).await, Ok(true));
}
#[tokio::test]
async fn test_remove_dependency() {
let manager = TaskManager::new();
let task_a = manager
.create_task("Task A".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let task_b = manager
.create_task("Task B".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
manager.add_dependency(&task_b, &task_a).await.unwrap();
let b = manager.get_task(&task_b).await.unwrap();
assert_eq!(b.status, TaskStatus::Blocked);
manager.remove_dependency(&task_b, &task_a).await.unwrap();
let b = manager.get_task(&task_b).await.unwrap();
assert_eq!(b.status, TaskStatus::Pending);
}
#[tokio::test]
async fn test_block_task() {
let manager = TaskManager::new();
let id = manager
.create_task("Block me".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
manager
.block_task(&id, Some("Waiting on external".to_string()))
.await
.unwrap();
let task = manager.get_task(&id).await.unwrap();
assert_eq!(task.status, TaskStatus::Blocked);
assert_eq!(task.summary, Some("Waiting on external".to_string()));
}
#[tokio::test]
async fn test_format_duration() {
use super::time_tracking::format_duration_secs;
assert_eq!(format_duration_secs(30), "30s");
assert_eq!(format_duration_secs(90), "1m 30s");
assert_eq!(format_duration_secs(3600), "1h 0m");
assert_eq!(format_duration_secs(3665), "1h 1m");
assert_eq!(format_duration_secs(-1), "-");
}
#[tokio::test]
async fn test_skipped_in_stats() {
let manager = TaskManager::new();
let id1 = manager
.create_task("Task 1".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
let id2 = manager
.create_task("Task 2".to_string(), None, TaskPriority::Normal)
.await
.unwrap();
manager.skip_task(&id1, None).await.unwrap();
manager
.complete_task(&id2, "Done".to_string())
.await
.unwrap();
let stats = manager.get_stats().await;
assert_eq!(stats.total, 2);
assert_eq!(stats.skipped, 1);
assert_eq!(stats.completed, 1);
}