Skip to main content

max / goingson

4.9 KB · 134 lines History Blame Raw
1 //! Integration tests for SqliteSyncAccountRepository.
2
3 mod common;
4
5 use goingson_core::SyncAccountRepository;
6 use goingson_db_sqlite::SqliteSyncAccountRepository;
7
8 #[tokio::test]
9 async fn create_applies_schema_defaults() {
10 let pool = common::setup_test_db().await;
11 let user_id = common::create_test_user(&pool).await;
12 let repo = SqliteSyncAccountRepository::new(pool.clone());
13
14 let acct = repo
15 .create(user_id, "google", "Work Calendar", Some("me@example.com"))
16 .await
17 .unwrap();
18
19 assert_eq!(acct.provider, "google");
20 assert_eq!(acct.account_name, "Work Calendar");
21 assert_eq!(acct.email.as_deref(), Some("me@example.com"));
22 // Defaults from migration 037.
23 assert!(acct.sync_calendars);
24 assert!(acct.sync_contacts);
25 assert!(acct.enabled);
26 assert_eq!(acct.sync_interval_minutes, 15);
27 assert!(acct.calendar_ids.is_empty(), "calendar_ids defaults to '[]'");
28 assert!(acct.last_calendar_sync.is_none());
29 }
30
31 #[tokio::test]
32 async fn create_allows_null_email() {
33 let pool = common::setup_test_db().await;
34 let user_id = common::create_test_user(&pool).await;
35 let repo = SqliteSyncAccountRepository::new(pool.clone());
36
37 let acct = repo.create(user_id, "caldav", "Personal", None).await.unwrap();
38 assert!(acct.email.is_none());
39
40 let fetched = repo.get_by_id(acct.id, user_id).await.unwrap().unwrap();
41 assert!(fetched.email.is_none());
42 }
43
44 #[tokio::test]
45 async fn get_by_id_missing_is_none() {
46 let pool = common::setup_test_db().await;
47 let user_id = common::create_test_user(&pool).await;
48 let repo = SqliteSyncAccountRepository::new(pool.clone());
49
50 let missing = goingson_core::SyncAccountId::new();
51 assert!(repo.get_by_id(missing, user_id).await.unwrap().is_none());
52 }
53
54 #[tokio::test]
55 async fn update_changes_fields_and_returns_row() {
56 let pool = common::setup_test_db().await;
57 let user_id = common::create_test_user(&pool).await;
58 let repo = SqliteSyncAccountRepository::new(pool.clone());
59
60 let acct = repo.create(user_id, "google", "Old Name", None).await.unwrap();
61 let updated = repo
62 .update(acct.id, user_id, "New Name", false, false, false)
63 .await
64 .unwrap()
65 .expect("existing account updates to Some");
66
67 assert_eq!(updated.account_name, "New Name");
68 assert!(!updated.sync_calendars);
69 assert!(!updated.sync_contacts);
70 assert!(!updated.enabled);
71 assert_eq!(updated.id, acct.id);
72 }
73
74 #[tokio::test]
75 async fn update_unknown_id_returns_none() {
76 let pool = common::setup_test_db().await;
77 let user_id = common::create_test_user(&pool).await;
78 let repo = SqliteSyncAccountRepository::new(pool.clone());
79
80 let missing = goingson_core::SyncAccountId::new();
81 let result = repo
82 .update(missing, user_id, "x", true, true, true)
83 .await
84 .unwrap();
85 assert!(result.is_none(), "no rows affected -> None");
86 }
87
88 #[tokio::test]
89 async fn delete_removes_row_and_reports_hit() {
90 let pool = common::setup_test_db().await;
91 let user_id = common::create_test_user(&pool).await;
92 let repo = SqliteSyncAccountRepository::new(pool.clone());
93
94 let acct = repo.create(user_id, "google", "Temp", None).await.unwrap();
95 assert!(repo.delete(acct.id, user_id).await.unwrap(), "first delete hits");
96 assert!(repo.get_by_id(acct.id, user_id).await.unwrap().is_none());
97 assert!(!repo.delete(acct.id, user_id).await.unwrap(), "second delete is a miss");
98 }
99
100 #[tokio::test]
101 async fn list_all_scoped_per_user_and_ordered_by_created_at() {
102 let pool = common::setup_test_db().await;
103 let user_a = common::create_test_user(&pool).await;
104 let user_b = common::create_test_user(&pool).await;
105 let repo = SqliteSyncAccountRepository::new(pool.clone());
106
107 let first = repo.create(user_a, "google", "First", None).await.unwrap();
108 let second = repo.create(user_a, "caldav", "Second", None).await.unwrap();
109 repo.create(user_b, "google", "Other User", None).await.unwrap();
110
111 let a = repo.list_all(user_a).await.unwrap();
112 assert_eq!(a.len(), 2, "only user_a's accounts");
113 // Ordered by created_at ASC (first created first).
114 assert_eq!(a[0].id, first.id);
115 assert_eq!(a[1].id, second.id);
116 }
117
118 #[tokio::test]
119 async fn cross_user_access_is_denied() {
120 let pool = common::setup_test_db().await;
121 let owner = common::create_test_user(&pool).await;
122 let intruder = common::create_test_user(&pool).await;
123 let repo = SqliteSyncAccountRepository::new(pool.clone());
124
125 let acct = repo.create(owner, "google", "Owned", None).await.unwrap();
126
127 // Another user cannot read, update, or delete it.
128 assert!(repo.get_by_id(acct.id, intruder).await.unwrap().is_none());
129 assert!(repo.update(acct.id, intruder, "hijack", true, true, true).await.unwrap().is_none());
130 assert!(!repo.delete(acct.id, intruder).await.unwrap());
131 // Still intact for the owner.
132 assert!(repo.get_by_id(acct.id, owner).await.unwrap().is_some());
133 }
134