Skip to main content

max / goingson

4.7 KB · 169 lines History Blame Raw
1 //! Integration tests for saved view repository operations.
2
3 use goingson_core::{
4 NewSavedView, Priority, ProjectId, SortDirection, SortField, TaskStatus, ViewFilters, ViewType,
5 };
6
7 use crate::test_utils::setup_test_state;
8
9 fn view(name: &str, view_type: ViewType, pinned: bool) -> NewSavedView {
10 NewSavedView {
11 name: name.to_string(),
12 view_type,
13 filters: ViewFilters::default(),
14 sort_by: None,
15 sort_order: Some(SortDirection::Asc),
16 is_pinned: Some(pinned),
17 }
18 }
19
20 #[tokio::test]
21 async fn create_and_list_saved_view() {
22 let (state, user_id) = setup_test_state().await;
23
24 let created = state
25 .saved_views
26 .create(user_id, view("My Tasks", ViewType::Tasks, false))
27 .await
28 .unwrap();
29 assert_eq!(created.name, "My Tasks");
30 assert_eq!(created.view_type, ViewType::Tasks);
31 assert!(!created.is_pinned);
32
33 let all = state.saved_views.list_all(user_id).await.unwrap();
34 assert_eq!(all.len(), 1);
35 assert_eq!(all[0].id, created.id);
36 }
37
38 #[tokio::test]
39 async fn list_pinned_filters_to_pinned_only() {
40 let (state, user_id) = setup_test_state().await;
41
42 state
43 .saved_views
44 .create(user_id, view("Pinned", ViewType::Tasks, true))
45 .await
46 .unwrap();
47 state
48 .saved_views
49 .create(user_id, view("Unpinned", ViewType::Emails, false))
50 .await
51 .unwrap();
52
53 let pinned = state.saved_views.list_pinned(user_id).await.unwrap();
54 assert_eq!(pinned.len(), 1);
55 assert_eq!(pinned[0].name, "Pinned");
56 assert_eq!(state.saved_views.list_all(user_id).await.unwrap().len(), 2);
57 }
58
59 #[tokio::test]
60 async fn delete_saved_view() {
61 let (state, user_id) = setup_test_state().await;
62
63 let created = state
64 .saved_views
65 .create(user_id, view("Temp", ViewType::Events, false))
66 .await
67 .unwrap();
68
69 assert!(state.saved_views.delete(created.id, user_id).await.unwrap());
70 assert!(state
71 .saved_views
72 .get_by_id(created.id, user_id)
73 .await
74 .unwrap()
75 .is_none());
76 // Second delete finds nothing to remove.
77 assert!(!state.saved_views.delete(created.id, user_id).await.unwrap());
78 }
79
80 #[tokio::test]
81 async fn get_nonexistent_view_returns_none() {
82 let (state, user_id) = setup_test_state().await;
83
84 let fake_id = goingson_core::SavedViewId::from(uuid::Uuid::new_v4());
85 assert!(state
86 .saved_views
87 .get_by_id(fake_id, user_id)
88 .await
89 .unwrap()
90 .is_none());
91 }
92
93 /// The view's filter payload is stored as JSON and the sort config as text columns.
94 /// Verify the full query payload survives a create -> fetch round-trip.
95 #[tokio::test]
96 async fn filters_and_sort_round_trip() {
97 let (state, user_id) = setup_test_state().await;
98
99 let project_id = ProjectId::new();
100 let filters = ViewFilters {
101 status: Some(vec![TaskStatus::Pending, TaskStatus::Started]),
102 priority: Some(vec![Priority::High]),
103 project_id: Some(project_id),
104 is_snoozed: Some(true),
105 is_waiting: Some(false),
106 ..Default::default()
107 };
108
109 let created = state
110 .saved_views
111 .create(
112 user_id,
113 NewSavedView {
114 name: "Complex".to_string(),
115 view_type: ViewType::Tasks,
116 filters: filters.clone(),
117 sort_by: Some(SortField::Urgency),
118 sort_order: Some(SortDirection::Desc),
119 is_pinned: Some(true),
120 },
121 )
122 .await
123 .unwrap();
124
125 let fetched = state
126 .saved_views
127 .get_by_id(created.id, user_id)
128 .await
129 .unwrap()
130 .unwrap();
131
132 assert_eq!(fetched.filters.status, filters.status);
133 assert_eq!(fetched.filters.priority, filters.priority);
134 assert_eq!(fetched.filters.project_id, Some(project_id));
135 assert_eq!(fetched.filters.is_snoozed, Some(true));
136 assert_eq!(fetched.filters.is_waiting, Some(false));
137 assert_eq!(fetched.sort_by, Some(SortField::Urgency));
138 assert_eq!(fetched.sort_order, SortDirection::Desc);
139 assert!(fetched.is_pinned);
140 }
141
142 #[tokio::test]
143 async fn toggle_pinned_flips_state() {
144 let (state, user_id) = setup_test_state().await;
145
146 let created = state
147 .saved_views
148 .create(user_id, view("Toggle", ViewType::Tasks, false))
149 .await
150 .unwrap();
151 assert!(!created.is_pinned);
152
153 let on = state
154 .saved_views
155 .toggle_pinned(created.id, user_id)
156 .await
157 .unwrap()
158 .unwrap();
159 assert!(on.is_pinned);
160
161 let off = state
162 .saved_views
163 .toggle_pinned(created.id, user_id)
164 .await
165 .unwrap()
166 .unwrap();
167 assert!(!off.is_pinned);
168 }
169