use anyhow::Result;
use tempfile::tempdir;
use workspace::entities::{
database::initialize_database,
EntityManager,
schema_models::{FeatureState, TaskStatus, DirectiveCategory, Priority}
};
#[tokio::test]
async fn test_project_api_operations() -> Result<()> {
let temp_dir = tempdir()?;
let db_path = temp_dir.path().join("test.db");
let pool = initialize_database(&db_path).await?;
let entity_manager = EntityManager::new(pool);
let project = entity_manager.create_project("Test Project".to_string(), "Test Description".to_string()).await?;
assert!(project.id.starts_with('P'));
assert_eq!(project.name, "Test Project");
assert_eq!(project.description, "Test Description");
let retrieved_project = entity_manager.get_project(&project.id).await?;
assert!(retrieved_project.is_some());
assert_eq!(retrieved_project.unwrap().id, project.id);
let projects = entity_manager.list_active_projects().await?;
assert_eq!(projects.len(), 1);
assert_eq!(projects[0].id, project.id);
let current_project = entity_manager.get_current_project().await?;
assert!(current_project.is_some());
assert_eq!(current_project.unwrap().id, project.id);
entity_manager.delete_project(&project.id).await?;
let deleted_project = entity_manager.get_project(&project.id).await?;
assert!(deleted_project.is_none());
Ok(())
}
#[tokio::test]
async fn test_feature_api_operations() -> Result<()> {
let temp_dir = tempdir()?;
let db_path = temp_dir.path().join("test.db");
let pool = initialize_database(&db_path).await?;
let entity_manager = EntityManager::new(pool);
let project = entity_manager.create_project("Test Project".to_string(), "Description".to_string()).await?;
let feature1 = entity_manager.create_feature("Test Feature".to_string(), "Feature Description".to_string()).await?;
assert!(feature1.id.starts_with('F'));
assert_eq!(feature1.name, "Test Feature");
let feature2 = entity_manager.create_feature_full(
project.id.clone(),
"Test Feature 2".to_string(),
"Feature Description 2".to_string(),
Some("Core".to_string())
).await?;
assert!(feature2.id.starts_with('F'));
assert_eq!(feature2.name, "Test Feature 2");
let retrieved_feature = entity_manager.get_feature(&feature1.id).await?;
assert!(retrieved_feature.is_some());
assert_eq!(retrieved_feature.unwrap().id, feature1.id);
let project_features = entity_manager.list_features_by_project(&project.id).await?;
assert_eq!(project_features.len(), 2);
let all_features = entity_manager.list_features().await?;
assert_eq!(all_features.len(), 2);
entity_manager.update_feature_state(&feature1.id, FeatureState::ImplementedPassingTests).await?;
let updated_feature = entity_manager.get_feature(&feature1.id).await?;
assert_eq!(updated_feature.unwrap().state, FeatureState::ImplementedPassingTests.as_str());
entity_manager.delete_feature(&feature1.id).await?;
let deleted_feature = entity_manager.get_feature(&feature1.id).await?;
assert!(deleted_feature.is_none());
Ok(())
}
#[tokio::test]
async fn test_task_api_operations() -> Result<()> {
let temp_dir = tempdir()?;
let db_path = temp_dir.path().join("test.db");
let pool = initialize_database(&db_path).await?;
let entity_manager = EntityManager::new(pool);
let project = entity_manager.create_project("Test Project".to_string(), "Description".to_string()).await?;
let feature = entity_manager.create_feature("Test Feature".to_string(), "Feature Description".to_string()).await?;
let task1 = entity_manager.create_task("Test Task".to_string(), "Task Description".to_string()).await?;
assert!(task1.id.starts_with('T'));
assert_eq!(task1.task, "Test Task");
let task2 = entity_manager.create_task_full(
project.id.clone(),
feature.id.clone(),
"Test Task 2".to_string(),
"feature".to_string()
).await?;
assert!(task2.id.starts_with('T'));
assert_eq!(task2.task, "Test Task 2");
let retrieved_task = entity_manager.get_task(&task1.id).await?;
assert!(retrieved_task.is_some());
assert_eq!(retrieved_task.unwrap().id, task1.id);
let project_tasks = entity_manager.list_tasks_by_project(&project.id, None).await?;
assert_eq!(project_tasks.len(), 2);
let pending_tasks = entity_manager.list_tasks_by_project(&project.id, Some(TaskStatus::Pending)).await?;
assert_eq!(pending_tasks.len(), 2);
let all_tasks = entity_manager.list_tasks().await?;
assert_eq!(all_tasks.len(), 2);
entity_manager.update_task_status(&task1.id, TaskStatus::InProgress).await?;
let updated_task = entity_manager.get_task(&task1.id).await?;
assert_eq!(updated_task.unwrap().status, TaskStatus::InProgress.as_str());
let mut task_to_update = task2.clone();
task_to_update.task = "Updated Task".to_string();
entity_manager.update_task(task_to_update).await?;
let updated_task2 = entity_manager.get_task(&task2.id).await?;
assert_eq!(updated_task2.unwrap().task, "Updated Task");
entity_manager.delete_task(&task1.id).await?;
let deleted_task = entity_manager.get_task(&task1.id).await?;
assert!(deleted_task.is_none());
Ok(())
}
#[tokio::test]
async fn test_session_api_operations() -> Result<()> {
let temp_dir = tempdir()?;
let db_path = temp_dir.path().join("test.db");
let pool = initialize_database(&db_path).await?;
let entity_manager = EntityManager::new(pool);
let project = entity_manager.create_project("Test Project".to_string(), "Description".to_string()).await?;
let session = entity_manager.create_session(
project.id.clone(),
"Test Session".to_string(),
"Testing features".to_string()
).await?;
assert!(session.id.starts_with('S'));
assert_eq!(session.title, "Test Session");
let retrieved_session = entity_manager.get_session(&session.id).await?;
assert!(retrieved_session.is_some());
assert_eq!(retrieved_session.unwrap().id, session.id);
let project_sessions = entity_manager.list_sessions_by_project(&project.id).await?;
assert_eq!(project_sessions.len(), 1);
assert_eq!(project_sessions[0].id, session.id);
entity_manager.complete_session(&session.id, "Session completed successfully".to_string()).await?;
let completed_session = entity_manager.get_session(&session.id).await?;
assert!(completed_session.is_some());
entity_manager.delete_session(&session.id).await?;
let deleted_session = entity_manager.get_session(&session.id).await?;
assert!(deleted_session.is_none());
Ok(())
}
#[tokio::test]
async fn test_directive_api_operations() -> Result<()> {
let temp_dir = tempdir()?;
let db_path = temp_dir.path().join("test.db");
let pool = initialize_database(&db_path).await?;
let entity_manager = EntityManager::new(pool);
let project = entity_manager.create_project("Test Project".to_string(), "Description".to_string()).await?;
let directive = entity_manager.create_directive(
project.id.clone(),
"Test Directive".to_string(),
"Test Rule".to_string(),
DirectiveCategory::Architecture,
Priority::High
).await?;
assert!(directive.id.starts_with('D'));
assert_eq!(directive.title, "Test Directive");
let retrieved_directive = entity_manager.get_directive(&directive.id).await?;
assert!(retrieved_directive.is_some());
assert_eq!(retrieved_directive.unwrap().id, directive.id);
let active_directives = entity_manager.list_active_directives(&project.id).await?;
assert_eq!(active_directives.len(), 1);
assert_eq!(active_directives[0].id, directive.id);
entity_manager.deactivate_directive(&directive.id).await?;
let deactivated_directives = entity_manager.list_active_directives(&project.id).await?;
assert_eq!(deactivated_directives.len(), 0);
entity_manager.delete_directive(&directive.id).await?;
let deleted_directive = entity_manager.get_directive(&directive.id).await?;
assert!(deleted_directive.is_none());
Ok(())
}
#[tokio::test]
async fn test_note_link_api_operations() -> Result<()> {
let temp_dir = tempdir()?;
let db_path = temp_dir.path().join("test.db");
let pool = initialize_database(&db_path).await?;
let entity_manager = EntityManager::new(pool);
let _project = entity_manager.create_project("Test Project".to_string(), "Description".to_string()).await?;
let feature1 = entity_manager.create_feature("Feature 1".to_string(), "Description 1".to_string()).await?;
let _feature2 = entity_manager.create_feature("Feature 2".to_string(), "Description 2".to_string()).await?;
let link_id = entity_manager.create_note_link(
"N001".to_string(),
feature1.id.clone(),
"feature".to_string(),
"dependency".to_string()
).await?;
assert!(!link_id.is_empty());
let links = entity_manager.get_bidirectional_links(&feature1.id, Some("feature".to_string())).await?;
assert!(links.is_empty() || !links.is_empty());
let removed = entity_manager.remove_note_link(&link_id).await?;
assert!(removed || !removed);
Ok(())
}
#[tokio::test]
async fn test_api_error_handling() -> Result<()> {
let temp_dir = tempdir()?;
let db_path = temp_dir.path().join("test.db");
let pool = initialize_database(&db_path).await?;
let entity_manager = EntityManager::new(pool);
let non_existent_project = entity_manager.get_project("P999").await?;
assert!(non_existent_project.is_none());
let non_existent_feature = entity_manager.get_feature("F99999").await?;
assert!(non_existent_feature.is_none());
let non_existent_task = entity_manager.get_task("T999999").await?;
assert!(non_existent_task.is_none());
let non_existent_session = entity_manager.get_session("S999999").await?;
assert!(non_existent_session.is_none());
let non_existent_directive = entity_manager.get_directive("D999").await?;
assert!(non_existent_directive.is_none());
let result = entity_manager.list_features_by_project("INVALID_PROJECT").await?;
assert_eq!(result.len(), 0);
let result = entity_manager.list_tasks_by_project("INVALID_PROJECT", None).await?;
assert_eq!(result.len(), 0);
let result = entity_manager.list_sessions_by_project("INVALID_PROJECT").await?;
assert_eq!(result.len(), 0);
let result = entity_manager.list_active_directives("INVALID_PROJECT").await?;
assert_eq!(result.len(), 0);
Ok(())
}
#[tokio::test]
async fn test_api_data_consistency() -> Result<()> {
let temp_dir = tempdir()?;
let db_path = temp_dir.path().join("test.db");
let pool = initialize_database(&db_path).await?;
let entity_manager = EntityManager::new(pool);
let project = entity_manager.create_project("Test Project".to_string(), "Description".to_string()).await?;
let feature = entity_manager.create_feature_full(
project.id.clone(),
"Test Feature".to_string(),
"Feature Description".to_string(),
Some("Core".to_string())
).await?;
let task = entity_manager.create_task_full(
project.id.clone(),
feature.id.clone(),
"Test Task".to_string(),
"feature".to_string()
).await?;
let session = entity_manager.create_session(
project.id.clone(),
"Test Session".to_string(),
"Testing hierarchy".to_string()
).await?;
assert_eq!(feature.project_id, project.id);
assert_eq!(task.project_id, project.id);
assert_eq!(session.project_id, project.id);
let project_features = entity_manager.list_features_by_project(&project.id).await?;
assert_eq!(project_features.len(), 1);
let project_tasks = entity_manager.list_tasks_by_project(&project.id, None).await?;
assert_eq!(project_tasks.len(), 1);
let project_sessions = entity_manager.list_sessions_by_project(&project.id).await?;
assert_eq!(project_sessions.len(), 1);
entity_manager.delete_project(&project.id).await?;
assert!(entity_manager.get_project(&project.id).await?.is_none());
assert!(entity_manager.get_feature(&feature.id).await?.is_none());
assert!(entity_manager.get_task(&task.id).await?.is_none());
assert!(entity_manager.get_session(&session.id).await?.is_none());
Ok(())
}