Skip to main content

max / goingson

5.0 KB · 150 lines History Blame Raw
1 //! Integration tests for annotation methods on SqliteTaskRepository.
2
3 mod common;
4
5 use goingson_core::TaskRepository;
6 use goingson_db_sqlite::SqliteTaskRepository;
7
8 #[tokio::test]
9 async fn test_add_annotation_and_get() {
10 let pool = common::setup_test_db().await;
11 let user_id = common::create_test_user(&pool).await;
12 let task_id = common::create_test_task(&pool, user_id).await;
13 let repo = SqliteTaskRepository::new(pool);
14
15 let annotation = repo
16 .add_annotation(task_id, user_id, "First note")
17 .await
18 .expect("Failed to add annotation");
19 assert!(annotation.is_some(), "Should return Some for valid task/user");
20
21 let annotation = annotation.unwrap();
22 assert_eq!(annotation.task_id, task_id);
23 assert_eq!(annotation.note, "First note");
24
25 let annotations = repo
26 .get_annotations_for_task(task_id)
27 .await
28 .expect("Failed to get annotations");
29 assert_eq!(annotations.len(), 1);
30 assert_eq!(annotations[0].id, annotation.id);
31 assert_eq!(annotations[0].note, "First note");
32 }
33
34 #[tokio::test]
35 async fn test_annotations_ordered_by_timestamp_desc() {
36 let pool = common::setup_test_db().await;
37 let user_id = common::create_test_user(&pool).await;
38 let task_id = common::create_test_task(&pool, user_id).await;
39 let repo = SqliteTaskRepository::new(pool);
40
41 repo.add_annotation(task_id, user_id, "Older note")
42 .await
43 .expect("Failed to add annotation")
44 .unwrap();
45
46 // Sleep to ensure a different second-precision timestamp
47 tokio::time::sleep(std::time::Duration::from_secs(1)).await;
48
49 let second = repo
50 .add_annotation(task_id, user_id, "Newer note")
51 .await
52 .expect("Failed to add annotation")
53 .unwrap();
54
55 let annotations = repo
56 .get_annotations_for_task(task_id)
57 .await
58 .expect("Failed to get annotations");
59 assert_eq!(annotations.len(), 2);
60
61 // Newest first (ORDER BY timestamp DESC)
62 assert_eq!(annotations[0].id, second.id);
63 assert_eq!(annotations[0].note, "Newer note");
64 assert_eq!(annotations[1].note, "Older note");
65 assert!(annotations[0].timestamp >= annotations[1].timestamp);
66 }
67
68 #[tokio::test]
69 async fn test_add_annotation_wrong_user_returns_none() {
70 let pool = common::setup_test_db().await;
71 let user1 = common::create_test_user(&pool).await;
72 let user2 = common::create_test_user(&pool).await;
73 let task_id = common::create_test_task(&pool, user1).await;
74 let repo = SqliteTaskRepository::new(pool);
75
76 let result = repo
77 .add_annotation(task_id, user2, "Unauthorized note")
78 .await
79 .expect("Should not error, just return None");
80 assert!(result.is_none(), "Should return None when user doesn't own the task");
81 }
82
83 #[tokio::test]
84 async fn test_delete_annotation() {
85 let pool = common::setup_test_db().await;
86 let user_id = common::create_test_user(&pool).await;
87 let task_id = common::create_test_task(&pool, user_id).await;
88 let repo = SqliteTaskRepository::new(pool);
89
90 let annotation = repo
91 .add_annotation(task_id, user_id, "To be deleted")
92 .await
93 .expect("Failed to add annotation")
94 .unwrap();
95
96 let deleted = repo
97 .delete_annotation(annotation.id, user_id)
98 .await
99 .expect("Failed to delete annotation");
100 assert!(deleted, "Should return true for successful deletion");
101
102 let annotations = repo
103 .get_annotations_for_task(task_id)
104 .await
105 .expect("Failed to get annotations");
106 assert!(annotations.is_empty(), "Annotation should be gone after deletion");
107 }
108
109 #[tokio::test]
110 async fn test_delete_annotation_wrong_user_returns_false() {
111 let pool = common::setup_test_db().await;
112 let user1 = common::create_test_user(&pool).await;
113 let user2 = common::create_test_user(&pool).await;
114 let task_id = common::create_test_task(&pool, user1).await;
115 let repo = SqliteTaskRepository::new(pool);
116
117 let annotation = repo
118 .add_annotation(task_id, user1, "User1's note")
119 .await
120 .expect("Failed to add annotation")
121 .unwrap();
122
123 let deleted = repo
124 .delete_annotation(annotation.id, user2)
125 .await
126 .expect("Should not error, just return false");
127 assert!(!deleted, "Should return false when user doesn't own the annotation");
128
129 // Verify the annotation still exists
130 let annotations = repo
131 .get_annotations_for_task(task_id)
132 .await
133 .expect("Failed to get annotations");
134 assert_eq!(annotations.len(), 1, "Annotation should still exist after unauthorized delete");
135 }
136
137 #[tokio::test]
138 async fn test_get_annotations_empty_task() {
139 let pool = common::setup_test_db().await;
140 let user_id = common::create_test_user(&pool).await;
141 let task_id = common::create_test_task(&pool, user_id).await;
142 let repo = SqliteTaskRepository::new(pool);
143
144 let annotations = repo
145 .get_annotations_for_task(task_id)
146 .await
147 .expect("Failed to get annotations");
148 assert!(annotations.is_empty(), "New task should have no annotations");
149 }
150