Skip to main content

max / goingson

5.7 KB · 216 lines History Blame Raw
1 //! Integration tests for contact repository operations.
2
3 use goingson_core::{NewContact, NewContactEmail, NewContactPhone, UpdateContact};
4
5 use crate::test_utils::setup_test_state;
6
7 #[tokio::test]
8 async fn create_and_list_contact() {
9 let (state, user_id) = setup_test_state().await;
10
11 let new_contact = NewContact {
12 display_name: "Jane Smith".to_string(),
13 nickname: Some("Janie".to_string()),
14 company: Some("Acme Corp".to_string()),
15 title: Some("Engineer".to_string()),
16 notes: "Met at conference".to_string(),
17 tags: vec!["work".to_string()],
18 birthday: None,
19 timezone: None,
20 is_implicit: false,
21 };
22
23 let contact = state.contacts.create(user_id, new_contact).await.unwrap();
24 assert_eq!(contact.display_name, "Jane Smith");
25 assert_eq!(contact.nickname, Some("Janie".to_string()));
26 assert_eq!(contact.company, Some("Acme Corp".to_string()));
27
28 let contacts = state.contacts.list_all(user_id).await.unwrap();
29 assert_eq!(contacts.len(), 1);
30 assert_eq!(contacts[0].display_name, "Jane Smith");
31 }
32
33 #[tokio::test]
34 async fn add_email_and_phone() {
35 let (state, user_id) = setup_test_state().await;
36
37 let new_contact = NewContact {
38 display_name: "John Doe".to_string(),
39 nickname: None,
40 company: None,
41 title: None,
42 notes: String::new(),
43 tags: vec![],
44 birthday: None,
45 timezone: None,
46 is_implicit: false,
47 };
48
49 let contact = state.contacts.create(user_id, new_contact).await.unwrap();
50
51 // Add email
52 let email = state
53 .contacts
54 .add_email(
55 contact.id,
56 user_id,
57 NewContactEmail {
58 address: "john@example.com".to_string(),
59 label: "Work".to_string(),
60 is_primary: true,
61 },
62 )
63 .await
64 .unwrap();
65 assert_eq!(email.address, "john@example.com");
66 assert!(email.is_primary);
67
68 // Add phone
69 let phone = state
70 .contacts
71 .add_phone(
72 contact.id,
73 user_id,
74 NewContactPhone {
75 number: "+1-555-0100".to_string(),
76 label: "Mobile".to_string(),
77 is_primary: true,
78 },
79 )
80 .await
81 .unwrap();
82 assert_eq!(phone.number, "+1-555-0100");
83
84 // Verify on get
85 let fetched = state
86 .contacts
87 .get_by_id(contact.id, user_id)
88 .await
89 .unwrap()
90 .unwrap();
91 assert_eq!(fetched.emails.len(), 1);
92 assert_eq!(fetched.emails[0].address, "john@example.com");
93 assert_eq!(fetched.phones.len(), 1);
94 assert_eq!(fetched.phones[0].number, "+1-555-0100");
95 }
96
97 #[tokio::test]
98 async fn update_contact() {
99 let (state, user_id) = setup_test_state().await;
100
101 let new_contact = NewContact {
102 display_name: "Original Name".to_string(),
103 nickname: None,
104 company: None,
105 title: None,
106 notes: String::new(),
107 tags: vec![],
108 birthday: None,
109 timezone: None,
110 is_implicit: false,
111 };
112
113 let contact = state.contacts.create(user_id, new_contact).await.unwrap();
114
115 let update = UpdateContact {
116 display_name: "Updated Name".to_string(),
117 nickname: Some("Nick".to_string()),
118 company: Some("New Corp".to_string()),
119 title: Some("Manager".to_string()),
120 notes: "Updated notes".to_string(),
121 tags: vec!["updated".to_string()],
122 birthday: None,
123 timezone: None,
124 };
125
126 let updated = state
127 .contacts
128 .update(contact.id, user_id, update)
129 .await
130 .unwrap()
131 .unwrap();
132 assert_eq!(updated.display_name, "Updated Name");
133 assert_eq!(updated.company, Some("New Corp".to_string()));
134 assert_eq!(updated.title, Some("Manager".to_string()));
135 }
136
137 #[tokio::test]
138 async fn delete_contact() {
139 let (state, user_id) = setup_test_state().await;
140
141 let new_contact = NewContact {
142 display_name: "To Delete".to_string(),
143 nickname: None,
144 company: None,
145 title: None,
146 notes: String::new(),
147 tags: vec![],
148 birthday: None,
149 timezone: None,
150 is_implicit: false,
151 };
152
153 let contact = state.contacts.create(user_id, new_contact).await.unwrap();
154
155 let deleted = state.contacts.delete(contact.id, user_id).await.unwrap();
156 assert!(deleted);
157
158 let fetched = state
159 .contacts
160 .get_by_id(contact.id, user_id)
161 .await
162 .unwrap();
163 assert!(fetched.is_none());
164 }
165
166 #[tokio::test]
167 async fn find_contact_by_email() {
168 let (state, user_id) = setup_test_state().await;
169
170 let new_contact = NewContact {
171 display_name: "Findable Person".to_string(),
172 nickname: None,
173 company: None,
174 title: None,
175 notes: String::new(),
176 tags: vec![],
177 birthday: None,
178 timezone: None,
179 is_implicit: false,
180 };
181
182 let contact = state.contacts.create(user_id, new_contact).await.unwrap();
183
184 // Add an email address
185 state
186 .contacts
187 .add_email(
188 contact.id,
189 user_id,
190 NewContactEmail {
191 address: "findable@example.com".to_string(),
192 label: "Work".to_string(),
193 is_primary: true,
194 },
195 )
196 .await
197 .unwrap();
198
199 // Find by email
200 let found = state
201 .contacts
202 .find_by_email(user_id, "findable@example.com")
203 .await
204 .unwrap();
205 assert!(found.is_some());
206 assert_eq!(found.unwrap().display_name, "Findable Person");
207
208 // Not found with different email
209 let not_found = state
210 .contacts
211 .find_by_email(user_id, "nonexistent@example.com")
212 .await
213 .unwrap();
214 assert!(not_found.is_none());
215 }
216