sync from monorepo @ 2452e92e
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
//! Integration tests for project CRUD lifecycle.
|
||||
|
||||
use dirigent_projects::{
|
||||
CreateProjectParams, FileBasedProjectStore, ProjectFilter, ProjectStore, ProjectUpdate,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
async fn make_store() -> FileBasedProjectStore {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
FileBasedProjectStore::new(dir.into_path()).await.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_and_get_project() {
|
||||
let store = make_store().await;
|
||||
let owner = Uuid::now_v7();
|
||||
|
||||
let project = store
|
||||
.create_project(CreateProjectParams {
|
||||
name: "Test Project".to_string(),
|
||||
description: "A test".to_string(),
|
||||
icon: Some("🚀".to_string()),
|
||||
owner,
|
||||
tags: vec!["rust".to_string()],
|
||||
languages: vec!["Rust".to_string()],
|
||||
metadata: serde_json::json!({}),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(project.name, "Test Project");
|
||||
assert_eq!(project.owner, owner);
|
||||
|
||||
let fetched = store.get_project(&project.id).await.unwrap();
|
||||
assert_eq!(fetched.id, project.id);
|
||||
assert_eq!(fetched.name, "Test Project");
|
||||
assert_eq!(fetched.icon, Some("🚀".to_string()));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_list_projects_empty() {
|
||||
let store = make_store().await;
|
||||
let projects = store.list_projects(ProjectFilter::default()).await.unwrap();
|
||||
assert!(projects.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_list_projects_with_filter() {
|
||||
let store = make_store().await;
|
||||
let owner1 = Uuid::now_v7();
|
||||
let owner2 = Uuid::now_v7();
|
||||
|
||||
store
|
||||
.create_project(CreateProjectParams {
|
||||
name: "Alpha".to_string(),
|
||||
owner: owner1,
|
||||
tags: vec!["web".to_string()],
|
||||
..default_params()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
store
|
||||
.create_project(CreateProjectParams {
|
||||
name: "Beta".to_string(),
|
||||
owner: owner2,
|
||||
tags: vec!["cli".to_string()],
|
||||
..default_params()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Filter by owner
|
||||
let filtered = store
|
||||
.list_projects(ProjectFilter {
|
||||
owner: Some(owner1),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(filtered.len(), 1);
|
||||
assert_eq!(filtered[0].name, "Alpha");
|
||||
|
||||
// Filter by name
|
||||
let filtered = store
|
||||
.list_projects(ProjectFilter {
|
||||
name_contains: Some("bet".to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(filtered.len(), 1);
|
||||
assert_eq!(filtered[0].name, "Beta");
|
||||
|
||||
// Filter by tag
|
||||
let filtered = store
|
||||
.list_projects(ProjectFilter {
|
||||
tags: vec!["web".to_string()],
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(filtered.len(), 1);
|
||||
assert_eq!(filtered[0].name, "Alpha");
|
||||
|
||||
// No filter returns all, sorted by name
|
||||
let all = store.list_projects(ProjectFilter::default()).await.unwrap();
|
||||
assert_eq!(all.len(), 2);
|
||||
assert_eq!(all[0].name, "Alpha");
|
||||
assert_eq!(all[1].name, "Beta");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_update_project() {
|
||||
let store = make_store().await;
|
||||
|
||||
let project = store
|
||||
.create_project(CreateProjectParams {
|
||||
name: "Original".to_string(),
|
||||
..default_params()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let updated = store
|
||||
.update_project(
|
||||
&project.id,
|
||||
ProjectUpdate {
|
||||
name: Some("Renamed".to_string()),
|
||||
description: Some("New description".to_string()),
|
||||
tags: Some(vec!["new-tag".to_string()]),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(updated.name, "Renamed");
|
||||
assert_eq!(updated.description, "New description");
|
||||
assert_eq!(updated.tags, vec!["new-tag"]);
|
||||
assert!(updated.updated_at > project.created_at);
|
||||
|
||||
// Verify persistence
|
||||
let fetched = store.get_project(&project.id).await.unwrap();
|
||||
assert_eq!(fetched.name, "Renamed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_delete_project() {
|
||||
let store = make_store().await;
|
||||
|
||||
let project = store
|
||||
.create_project(CreateProjectParams {
|
||||
name: "ToDelete".to_string(),
|
||||
..default_params()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
store.delete_project(&project.id).await.unwrap();
|
||||
|
||||
let err = store.get_project(&project.id).await.unwrap_err();
|
||||
assert!(matches!(err, dirigent_projects::ProjectError::NotFound(_)));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_nonexistent_project() {
|
||||
let store = make_store().await;
|
||||
let err = store.get_project(&Uuid::now_v7()).await.unwrap_err();
|
||||
assert!(matches!(err, dirigent_projects::ProjectError::NotFound(_)));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_empty_name_fails() {
|
||||
let store = make_store().await;
|
||||
let err = store
|
||||
.create_project(CreateProjectParams {
|
||||
name: " ".to_string(),
|
||||
..default_params()
|
||||
})
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert!(matches!(
|
||||
err,
|
||||
dirigent_projects::ProjectError::Validation(_)
|
||||
));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_update_empty_name_fails() {
|
||||
let store = make_store().await;
|
||||
let project = store
|
||||
.create_project(CreateProjectParams {
|
||||
name: "Valid".to_string(),
|
||||
..default_params()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let err = store
|
||||
.update_project(
|
||||
&project.id,
|
||||
ProjectUpdate {
|
||||
name: Some("".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert!(matches!(
|
||||
err,
|
||||
dirigent_projects::ProjectError::Validation(_)
|
||||
));
|
||||
}
|
||||
|
||||
fn default_params() -> CreateProjectParams {
|
||||
CreateProjectParams {
|
||||
name: String::new(),
|
||||
description: String::new(),
|
||||
icon: None,
|
||||
owner: Uuid::now_v7(),
|
||||
tags: vec![],
|
||||
languages: vec![],
|
||||
metadata: serde_json::json!({}),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user