Skip to main content

max / goingson

9.8 KB · 285 lines History Blame Raw
1 //! Integration tests for SqliteEmailRepository.
2
3 mod common;
4
5 use chrono::{Duration, Utc};
6 use goingson_core::{EmailRepository, NewEmail};
7 use goingson_db_sqlite::SqliteEmailRepository;
8
9 #[tokio::test]
10 async fn test_create_and_get_email() {
11 let pool = common::setup_test_db().await;
12 let user_id = common::create_test_user(&pool).await;
13 let repo = SqliteEmailRepository::new(pool);
14
15 let new_email = NewEmail {
16 project_id: None,
17 from_address: "sender@example.com".to_string(),
18 to_address: "recipient@example.com".to_string(),
19 subject: "Test Subject".to_string(),
20 body: "Test email body content".to_string(),
21 is_read: false,
22 received_at: Some(Utc::now()),
23 };
24
25 let created = repo.create(user_id, new_email).await.expect("Failed to create email");
26 assert_eq!(created.subject, "Test Subject");
27 assert_eq!(created.from, "sender@example.com");
28 assert!(!created.is_read);
29 assert!(!created.is_archived);
30
31 let fetched = repo.get_by_id(created.id, user_id).await.expect("Failed to get email");
32 assert!(fetched.is_some());
33 assert_eq!(fetched.unwrap().id, created.id);
34 }
35
36 #[tokio::test]
37 async fn test_email_read_unread() {
38 let pool = common::setup_test_db().await;
39 let user_id = common::create_test_user(&pool).await;
40 let repo = SqliteEmailRepository::new(pool);
41
42 let new_email = NewEmail {
43 project_id: None,
44 from_address: "sender@example.com".to_string(),
45 to_address: "recipient@example.com".to_string(),
46 subject: "Read/Unread test".to_string(),
47 body: "Test body".to_string(),
48 is_read: false,
49 received_at: Some(Utc::now()),
50 };
51
52 let email = repo.create(user_id, new_email).await.expect("Failed to create");
53 assert!(!email.is_read);
54
55 // Mark as read
56 let marked_read = repo.mark_read(email.id, user_id).await.expect("Failed to mark read");
57 assert!(marked_read);
58
59 // Verify it's read
60 let fetched = repo.get_by_id(email.id, user_id).await.expect("Failed to get").unwrap();
61 assert!(fetched.is_read);
62
63 // Mark as unread
64 let marked_unread = repo.mark_unread(email.id, user_id).await.expect("Failed to mark unread");
65 assert!(marked_unread);
66
67 // Verify it's unread
68 let fetched = repo.get_by_id(email.id, user_id).await.expect("Failed to get").unwrap();
69 assert!(!fetched.is_read);
70 }
71
72 #[tokio::test]
73 async fn test_email_archive() {
74 let pool = common::setup_test_db().await;
75 let user_id = common::create_test_user(&pool).await;
76 let repo = SqliteEmailRepository::new(pool);
77
78 let new_email = NewEmail {
79 project_id: None,
80 from_address: "sender@example.com".to_string(),
81 to_address: "recipient@example.com".to_string(),
82 subject: "Archive test".to_string(),
83 body: "Test body".to_string(),
84 is_read: false,
85 received_at: Some(Utc::now()),
86 };
87
88 let email = repo.create(user_id, new_email).await.expect("Failed to create");
89 assert!(!email.is_archived);
90
91 // Archive
92 let archived = repo.archive(email.id, user_id).await.expect("Failed to archive");
93 assert!(archived);
94
95 // Verify it's archived
96 let fetched = repo.get_by_id(email.id, user_id).await.expect("Failed to get").unwrap();
97 assert!(fetched.is_archived);
98
99 // Should not appear in non-archived list
100 let emails = repo.list_all(user_id, false).await.expect("Failed to list");
101 assert!(emails.iter().all(|e| e.id != email.id));
102
103 // Should appear in list with archived included
104 let all_emails = repo.list_all(user_id, true).await.expect("Failed to list all");
105 assert!(all_emails.iter().any(|e| e.id == email.id));
106
107 // Unarchive
108 let unarchived = repo.unarchive(email.id, user_id).await.expect("Failed to unarchive");
109 assert!(unarchived);
110
111 // Verify it's unarchived
112 let fetched = repo.get_by_id(email.id, user_id).await.expect("Failed to get").unwrap();
113 assert!(!fetched.is_archived);
114 }
115
116 #[tokio::test]
117 async fn test_email_snooze() {
118 let pool = common::setup_test_db().await;
119 let user_id = common::create_test_user(&pool).await;
120 let repo = SqliteEmailRepository::new(pool);
121
122 let new_email = NewEmail {
123 project_id: None,
124 from_address: "sender@example.com".to_string(),
125 to_address: "recipient@example.com".to_string(),
126 subject: "Snooze test".to_string(),
127 body: "Test body".to_string(),
128 is_read: false,
129 received_at: Some(Utc::now()),
130 };
131
132 let email = repo.create(user_id, new_email).await.expect("Failed to create");
133
134 let until = Utc::now() + Duration::hours(4);
135 let snoozed = repo.snooze(email.id, user_id, until).await.expect("Failed to snooze");
136 assert!(snoozed.is_some());
137 assert!(snoozed.as_ref().unwrap().snoozed_until.is_some());
138
139 // Should appear in snoozed list
140 let snoozed_emails = repo.list_snoozed(user_id).await.expect("Failed to list snoozed");
141 assert_eq!(snoozed_emails.len(), 1);
142
143 // Unsnooze
144 let unsnoozed = repo.unsnooze(email.id, user_id).await.expect("Failed to unsnooze");
145 assert!(unsnoozed.is_some());
146 assert!(unsnoozed.unwrap().snoozed_until.is_none());
147 }
148
149 #[tokio::test]
150 async fn test_email_waiting_for_response() {
151 let pool = common::setup_test_db().await;
152 let user_id = common::create_test_user(&pool).await;
153 let repo = SqliteEmailRepository::new(pool);
154
155 let new_email = NewEmail {
156 project_id: None,
157 from_address: "me@example.com".to_string(),
158 to_address: "them@example.com".to_string(),
159 subject: "Waiting test".to_string(),
160 body: "Test body".to_string(),
161 is_read: true,
162 received_at: Some(Utc::now()),
163 };
164
165 let email = repo.create(user_id, new_email).await.expect("Failed to create");
166
167 let expected = Utc::now() + Duration::days(2);
168 let waiting = repo.mark_waiting(email.id, user_id, Some(expected)).await.expect("Failed to mark waiting");
169 assert!(waiting.is_some());
170 assert!(waiting.as_ref().unwrap().waiting_for_response);
171
172 // Should appear in waiting list
173 let waiting_emails = repo.list_waiting(user_id).await.expect("Failed to list waiting");
174 assert_eq!(waiting_emails.len(), 1);
175
176 // Clear waiting
177 let cleared = repo.clear_waiting(email.id, user_id).await.expect("Failed to clear");
178 assert!(cleared.is_some());
179 assert!(!cleared.unwrap().waiting_for_response);
180 }
181
182 #[tokio::test]
183 async fn test_delete_email() {
184 let pool = common::setup_test_db().await;
185 let user_id = common::create_test_user(&pool).await;
186 let repo = SqliteEmailRepository::new(pool);
187
188 let new_email = NewEmail {
189 project_id: None,
190 from_address: "sender@example.com".to_string(),
191 to_address: "recipient@example.com".to_string(),
192 subject: "Delete test".to_string(),
193 body: "Test body".to_string(),
194 is_read: false,
195 received_at: Some(Utc::now()),
196 };
197
198 let email = repo.create(user_id, new_email).await.expect("Failed to create");
199
200 let deleted = repo.delete(email.id, user_id).await.expect("Failed to delete");
201 assert!(deleted);
202
203 let fetched = repo.get_by_id(email.id, user_id).await.expect("Failed to get");
204 assert!(fetched.is_none());
205 }
206
207 #[tokio::test]
208 async fn test_email_ordering_by_received_at() {
209 let pool = common::setup_test_db().await;
210 let user_id = common::create_test_user(&pool).await;
211 let repo = SqliteEmailRepository::new(pool);
212
213 // Create emails at different times
214 for i in 0..3 {
215 let new_email = NewEmail {
216 project_id: None,
217 from_address: "sender@example.com".to_string(),
218 to_address: "recipient@example.com".to_string(),
219 subject: format!("Email {}", i),
220 body: "Test body".to_string(),
221 is_read: false,
222 received_at: Some(Utc::now() - Duration::hours(i as i64)),
223 };
224 repo.create(user_id, new_email).await.expect("Failed to create");
225 }
226
227 let emails = repo.list_all(user_id, false).await.expect("Failed to list");
228 assert_eq!(emails.len(), 3);
229
230 // Should be ordered by received_at descending (newest first)
231 assert!(emails[0].received_at >= emails[1].received_at);
232 assert!(emails[1].received_at >= emails[2].received_at);
233 }
234
235 #[tokio::test]
236 async fn test_count_unread() {
237 let pool = common::setup_test_db().await;
238 let user_id = common::create_test_user(&pool).await;
239 let repo = SqliteEmailRepository::new(pool);
240
241 // Create 3 emails, mark 1 as read
242 for i in 0..3 {
243 let new_email = NewEmail {
244 project_id: None,
245 from_address: "sender@example.com".to_string(),
246 to_address: "recipient@example.com".to_string(),
247 subject: format!("Email {}", i),
248 body: "Test body".to_string(),
249 is_read: i == 0, // First one is read
250 received_at: Some(Utc::now()),
251 };
252 repo.create(user_id, new_email).await.expect("Failed to create");
253 }
254
255 let count = repo.count_unread(user_id).await.expect("Failed to count");
256 assert_eq!(count, 2);
257 }
258
259 #[tokio::test]
260 async fn test_mark_all_read() {
261 let pool = common::setup_test_db().await;
262 let user_id = common::create_test_user(&pool).await;
263 let repo = SqliteEmailRepository::new(pool);
264
265 // Create 3 unread emails
266 for i in 0..3 {
267 let new_email = NewEmail {
268 project_id: None,
269 from_address: "sender@example.com".to_string(),
270 to_address: "recipient@example.com".to_string(),
271 subject: format!("Email {}", i),
272 body: "Test body".to_string(),
273 is_read: false,
274 received_at: Some(Utc::now()),
275 };
276 repo.create(user_id, new_email).await.expect("Failed to create");
277 }
278
279 let marked = repo.mark_all_read(user_id).await.expect("Failed to mark all read");
280 assert_eq!(marked, 3);
281
282 let count = repo.count_unread(user_id).await.expect("Failed to count");
283 assert_eq!(count, 0);
284 }
285