//! Integration tests for SqliteSavedViewRepository. mod common; use goingson_core::{ NewSavedView, Priority, ProjectId, SavedViewRepository, SortDirection, SortField, TaskStatus, ViewFilters, ViewType, }; use goingson_db_sqlite::SqliteSavedViewRepository; #[tokio::test] async fn test_create_and_get_saved_view() { let pool = common::setup_test_db().await; let user_id = common::create_test_user(&pool).await; let repo = SqliteSavedViewRepository::new(pool); let filters = ViewFilters { status: Some(vec![TaskStatus::Pending]), priority: Some(vec![Priority::High]), ..Default::default() }; let new_view = NewSavedView { name: "High Priority Pending".to_string(), view_type: ViewType::Tasks, filters, sort_by: Some(SortField::Urgency), sort_order: Some(SortDirection::Desc), is_pinned: Some(true), }; let created = repo.create(user_id, new_view).await.expect("Failed to create view"); assert_eq!(created.name, "High Priority Pending"); assert_eq!(created.view_type, ViewType::Tasks); assert!(created.is_pinned); let fetched = repo.get_by_id(created.id, user_id).await.expect("Failed to get view"); assert!(fetched.is_some()); let fetched = fetched.unwrap(); assert_eq!(fetched.id, created.id); assert_eq!(fetched.filters.status, Some(vec![TaskStatus::Pending])); } #[tokio::test] async fn test_list_pinned_views() { let pool = common::setup_test_db().await; let user_id = common::create_test_user(&pool).await; let repo = SqliteSavedViewRepository::new(pool); // Create pinned view let pinned = NewSavedView { name: "Pinned View".to_string(), view_type: ViewType::Tasks, filters: ViewFilters::default(), sort_by: None, sort_order: Some(SortDirection::Asc), is_pinned: Some(true), }; repo.create(user_id, pinned).await.expect("Failed to create"); // Create unpinned view let unpinned = NewSavedView { name: "Unpinned View".to_string(), view_type: ViewType::Tasks, filters: ViewFilters::default(), sort_by: None, sort_order: Some(SortDirection::Asc), is_pinned: Some(false), }; repo.create(user_id, unpinned).await.expect("Failed to create"); let pinned_views = repo.list_pinned(user_id).await.expect("Failed to list pinned"); assert_eq!(pinned_views.len(), 1); assert_eq!(pinned_views[0].name, "Pinned View"); let all_views = repo.list_all(user_id).await.expect("Failed to list all"); assert_eq!(all_views.len(), 2); } #[tokio::test] async fn test_toggle_pinned() { let pool = common::setup_test_db().await; let user_id = common::create_test_user(&pool).await; let repo = SqliteSavedViewRepository::new(pool); let new_view = NewSavedView { name: "Toggle Test".to_string(), view_type: ViewType::Emails, filters: ViewFilters::default(), sort_by: None, sort_order: Some(SortDirection::Desc), is_pinned: Some(false), }; let created = repo.create(user_id, new_view).await.expect("Failed to create"); assert!(!created.is_pinned); // Toggle to pinned let toggled = repo.toggle_pinned(created.id, user_id).await.expect("Failed to toggle"); assert!(toggled.is_some()); assert!(toggled.as_ref().unwrap().is_pinned); // Toggle back to unpinned let toggled = repo.toggle_pinned(created.id, user_id).await.expect("Failed to toggle"); assert!(toggled.is_some()); assert!(!toggled.unwrap().is_pinned); } #[tokio::test] async fn test_update_saved_view() { let pool = common::setup_test_db().await; let user_id = common::create_test_user(&pool).await; let repo = SqliteSavedViewRepository::new(pool); let new_view = NewSavedView { name: "Original Name".to_string(), view_type: ViewType::Tasks, filters: ViewFilters::default(), sort_by: None, sort_order: Some(SortDirection::Asc), is_pinned: Some(false), }; let created = repo.create(user_id, new_view).await.expect("Failed to create"); // Update the view let updated_filters = ViewFilters { status: Some(vec![TaskStatus::Completed]), ..Default::default() }; let update = NewSavedView { name: "Updated Name".to_string(), view_type: ViewType::Tasks, filters: updated_filters, sort_by: Some(SortField::CreatedAt), sort_order: Some(SortDirection::Desc), is_pinned: Some(true), }; let updated = repo.update(created.id, user_id, update).await.expect("Failed to update"); assert!(updated.is_some()); let updated = updated.unwrap(); assert_eq!(updated.name, "Updated Name"); assert!(updated.is_pinned); assert_eq!(updated.sort_order, SortDirection::Desc); } #[tokio::test] async fn test_delete_saved_view() { let pool = common::setup_test_db().await; let user_id = common::create_test_user(&pool).await; let repo = SqliteSavedViewRepository::new(pool); let new_view = NewSavedView { name: "To Delete".to_string(), view_type: ViewType::Events, filters: ViewFilters::default(), sort_by: None, sort_order: Some(SortDirection::Asc), is_pinned: Some(true), }; let created = repo.create(user_id, new_view).await.expect("Failed to create"); let deleted = repo.delete(created.id, user_id).await.expect("Failed to delete"); assert!(deleted); let fetched = repo.get_by_id(created.id, user_id).await.expect("Failed to get"); assert!(fetched.is_none()); } #[tokio::test] async fn test_view_filters_serialization() { let pool = common::setup_test_db().await; let user_id = common::create_test_user(&pool).await; let repo = SqliteSavedViewRepository::new(pool); let filters = ViewFilters { status: Some(vec![TaskStatus::Pending, TaskStatus::Started]), priority: Some(vec![Priority::High, Priority::Medium]), project_id: Some(ProjectId::new()), is_snoozed: Some(true), is_waiting: Some(false), ..Default::default() }; let new_view = NewSavedView { name: "Complex Filters".to_string(), view_type: ViewType::Tasks, filters: filters.clone(), sort_by: Some(SortField::Due), sort_order: Some(SortDirection::Asc), is_pinned: Some(true), }; let created = repo.create(user_id, new_view).await.expect("Failed to create"); let fetched = repo.get_by_id(created.id, user_id).await.expect("Failed to get"); assert!(fetched.is_some()); let fetched = fetched.unwrap(); // Verify all filter fields round-trip correctly assert_eq!(fetched.filters.status, filters.status); assert_eq!(fetched.filters.priority, filters.priority); assert_eq!(fetched.filters.project_id, filters.project_id); assert_eq!(fetched.filters.is_snoozed, filters.is_snoozed); assert_eq!(fetched.filters.is_waiting, filters.is_waiting); } #[tokio::test] async fn test_position_ordering() { let pool = common::setup_test_db().await; let user_id = common::create_test_user(&pool).await; let repo = SqliteSavedViewRepository::new(pool); // Create multiple pinned views for i in 1..=3 { let view = NewSavedView { name: format!("View {}", i), view_type: ViewType::Tasks, filters: ViewFilters::default(), sort_by: None, sort_order: Some(SortDirection::Asc), is_pinned: Some(true), }; repo.create(user_id, view).await.expect("Failed to create"); } let views = repo.list_pinned(user_id).await.expect("Failed to list"); assert_eq!(views.len(), 3); // Views should maintain consistent ordering // Position is assigned on creation (implementation dependent) for (i, view) in views.iter().enumerate() { assert_eq!(view.name, format!("View {}", i + 1)); } }