//! Integration tests for task commands. use goingson_core::{NewTask, Priority}; use crate::test_utils::{create_test_project, setup_test_state}; #[tokio::test] async fn test_create_task_success() { let (state, user_id) = setup_test_state().await; let project_id = create_test_project(&state, user_id).await; let new_task = NewTask::builder("Test task description") .project_id(project_id) .priority(Priority::Medium) .tag("test") .build(); let result = state.tasks.create(user_id, new_task).await; assert!(result.is_ok()); let task = result.unwrap(); assert_eq!(task.description, "Test task description"); assert_eq!(task.project_id, Some(project_id)); assert_eq!(task.priority, Priority::Medium); assert_eq!(task.tags, vec!["test"]); } #[tokio::test] async fn test_create_task_without_project() { let (state, user_id) = setup_test_state().await; let new_task = NewTask::builder("Standalone task") .priority(Priority::High) .build(); let result = state.tasks.create(user_id, new_task).await; assert!(result.is_ok()); let task = result.unwrap(); assert_eq!(task.description, "Standalone task"); assert!(task.project_id.is_none()); } #[tokio::test] async fn test_complete_task() { let (state, user_id) = setup_test_state().await; let new_task = NewTask::builder("Task to complete") .priority(Priority::Low) .build(); let task = state.tasks.create(user_id, new_task).await.unwrap(); let completed = state.tasks.complete(task.id, user_id).await.unwrap(); assert!(completed.is_some()); // Returns the completed task // Verify status changed let fetched = state.tasks.get_by_id(task.id, user_id).await.unwrap().unwrap(); assert_eq!(fetched.status, goingson_core::TaskStatus::Completed); } #[tokio::test] async fn test_list_tasks_filtered_by_status() { let (state, user_id) = setup_test_state().await; // Create pending task let pending = NewTask::builder("Pending task") .priority(Priority::Medium) .build(); state.tasks.create(user_id, pending).await.unwrap(); // Create and complete a task let to_complete = NewTask::builder("Completed task") .priority(Priority::Low) .build(); let task = state.tasks.create(user_id, to_complete).await.unwrap(); state.tasks.complete(task.id, user_id).await.unwrap(); // Filter for pending only let query = goingson_core::TaskFilterQuery { status: Some(goingson_core::TaskStatus::Pending), ..Default::default() }; let (tasks, total) = state.tasks.list_filtered(user_id, query).await.unwrap(); assert_eq!(total, 1); assert_eq!(tasks.len(), 1); assert_eq!(tasks[0].description, "Pending task"); } #[tokio::test] async fn test_list_tasks_filtered_by_priority() { let (state, user_id) = setup_test_state().await; // Create tasks with different priorities let high = NewTask::builder("High priority") .priority(Priority::High) .build(); state.tasks.create(user_id, high).await.unwrap(); let low = NewTask::builder("Low priority") .priority(Priority::Low) .build(); state.tasks.create(user_id, low).await.unwrap(); // Filter for high priority only let query = goingson_core::TaskFilterQuery { priority: Some(Priority::High), ..Default::default() }; let (tasks, total) = state.tasks.list_filtered(user_id, query).await.unwrap(); assert_eq!(total, 1); assert_eq!(tasks[0].description, "High priority"); } #[tokio::test] async fn test_list_tasks_pagination() { let (state, user_id) = setup_test_state().await; // Create 5 tasks for i in 0..5 { let task = NewTask::builder(format!("Task {}", i)) .priority(Priority::Medium) .urgency(5.0 - i as f64) // Decreasing urgency for predictable order .build(); state.tasks.create(user_id, task).await.unwrap(); } // Get first page (2 items) let query = goingson_core::TaskFilterQuery { limit: Some(2), offset: Some(0), ..Default::default() }; let (tasks, total) = state.tasks.list_filtered(user_id, query).await.unwrap(); assert_eq!(total, 5); assert_eq!(tasks.len(), 2); // Get second page let query = goingson_core::TaskFilterQuery { limit: Some(2), offset: Some(2), ..Default::default() }; let (tasks, _) = state.tasks.list_filtered(user_id, query).await.unwrap(); assert_eq!(tasks.len(), 2); } #[tokio::test] async fn test_task_with_subtasks() { let (state, user_id) = setup_test_state().await; let new_task = NewTask::builder("Task with subtasks") .priority(Priority::Medium) .build(); let task = state.tasks.create(user_id, new_task).await.unwrap(); // Add subtasks state.tasks.add_subtask(task.id, user_id, "Subtask 1").await.unwrap(); state.tasks.add_subtask(task.id, user_id, "Subtask 2").await.unwrap(); // Get task with subtasks let fetched = state.tasks.get_by_id(task.id, user_id).await.unwrap().unwrap(); assert_eq!(fetched.subtasks.len(), 2); assert_eq!(fetched.subtask_count(), 2); assert_eq!(fetched.subtasks_completed(), 0); // Complete a subtask let subtask_id = fetched.subtasks[0].id; state.tasks.toggle_subtask(subtask_id, user_id).await.unwrap(); // Verify completion let fetched = state.tasks.get_by_id(task.id, user_id).await.unwrap().unwrap(); assert_eq!(fetched.subtasks_completed(), 1); }