Skip to main content

max / makenotwork

9.6 KB · 305 lines History Blame Raw
1 use crate::harness::TestHarness;
2
3 #[tokio::test]
4 async fn mention_renders_as_profile_link() {
5 let mut h = TestHarness::new().await;
6 let author_id = h.login_as("mentionauth").await;
7 let comm_id = h.create_community("Test", "test").await;
8 let _cat_id = h.create_category(comm_id, "General", "general").await;
9 h.add_membership(author_id, comm_id, "member").await;
10
11 // Create the mentioned user via direct SQL (so author stays logged in)
12 let mentioned_id = uuid::Uuid::new_v4();
13 sqlx::query("INSERT INTO users (mnw_account_id, username, display_name) VALUES ($1, $2, $2)")
14 .bind(mentioned_id)
15 .bind("mentionee")
16 .execute(&h.db)
17 .await
18 .unwrap();
19 h.add_membership(mentioned_id, comm_id, "member").await;
20
21 // GET page for CSRF
22 h.client.get("/p/test/general/new").await;
23
24 // Create thread via HTTP with @mention
25 let resp = h
26 .client
27 .post_form(
28 "/p/test/general/new",
29 "title=Mention+Test&body=Hello+%40mentionee+welcome",
30 )
31 .await;
32 assert!(
33 resp.status.is_redirection(),
34 "Expected redirect, got {}",
35 resp.status
36 );
37
38 let threads =
39 mt_db::queries::list_threads_in_category_paginated(&h.db, "test", "general", 10, 0)
40 .await
41 .unwrap();
42 assert!(!threads.is_empty());
43 let thread_id = threads[0].id;
44
45 let thread_url = format!("/p/test/general/{thread_id}");
46 let resp = h.client.get(&thread_url).await;
47
48 assert!(
49 resp.text.contains("/p/test/u/mentionee"),
50 "Expected mention to render as profile link. Body: {}",
51 resp.text[resp.text.find("post-body").unwrap_or(0)..]
52 .chars()
53 .take(500)
54 .collect::<String>()
55 );
56 }
57
58 #[tokio::test]
59 async fn mention_stored_in_db() {
60 let mut h = TestHarness::new().await;
61 let author_id = h.login_as("mentiondbauth").await;
62 let comm_id = h.create_community("Test", "test").await;
63 let _cat_id = h.create_category(comm_id, "General", "general").await;
64 h.add_membership(author_id, comm_id, "member").await;
65
66 // Create the mentioned user via direct SQL (so author stays logged in)
67 let mentioned_id = uuid::Uuid::new_v4();
68 sqlx::query("INSERT INTO users (mnw_account_id, username, display_name) VALUES ($1, $2, $2)")
69 .bind(mentioned_id)
70 .bind("mentiondbuser")
71 .execute(&h.db)
72 .await
73 .unwrap();
74 h.add_membership(mentioned_id, comm_id, "member").await;
75
76 h.client.get("/p/test/general/new").await;
77 h.client
78 .post_form(
79 "/p/test/general/new",
80 "title=DB+Test&body=Hey+%40mentiondbuser",
81 )
82 .await;
83
84 let threads =
85 mt_db::queries::list_threads_in_category_paginated(&h.db, "test", "general", 10, 0)
86 .await
87 .unwrap();
88 let thread_id = threads[0].id;
89 let posts = mt_db::queries::list_posts_in_thread(&h.db, thread_id)
90 .await
91 .unwrap();
92 let post_id = posts[0].id;
93
94 let count: i64 = sqlx::query_scalar(
95 "SELECT COUNT(*) FROM post_mentions WHERE post_id = $1 AND mentioned_user_id = $2",
96 )
97 .bind(post_id)
98 .bind(mentioned_id)
99 .fetch_one(&h.db)
100 .await
101 .unwrap();
102
103 assert_eq!(count, 1, "Expected 1 mention row in DB");
104 }
105
106 #[tokio::test]
107 async fn self_mention_not_stored() {
108 let mut h = TestHarness::new().await;
109 let author_id = h.login_as("selfmentioner").await;
110 let comm_id = h.create_community("Test", "test").await;
111 let _cat_id = h.create_category(comm_id, "General", "general").await;
112 h.add_membership(author_id, comm_id, "member").await;
113
114 h.client.get("/p/test/general/new").await;
115 h.client
116 .post_form(
117 "/p/test/general/new",
118 "title=Self+Mention&body=I+am+%40selfmentioner",
119 )
120 .await;
121
122 let threads =
123 mt_db::queries::list_threads_in_category_paginated(&h.db, "test", "general", 10, 0)
124 .await
125 .unwrap();
126 let thread_id = threads[0].id;
127 let posts = mt_db::queries::list_posts_in_thread(&h.db, thread_id)
128 .await
129 .unwrap();
130 let post_id = posts[0].id;
131
132 let count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM post_mentions WHERE post_id = $1")
133 .bind(post_id)
134 .fetch_one(&h.db)
135 .await
136 .unwrap();
137
138 assert_eq!(count, 0, "Self-mention should not be stored in DB");
139 }
140
141 #[tokio::test]
142 async fn unknown_username_left_as_text() {
143 let mut h = TestHarness::new().await;
144 let author_id = h.login_as("unknownmentionauth").await;
145 let comm_id = h.create_community("Test", "test").await;
146 let _cat_id = h.create_category(comm_id, "General", "general").await;
147 h.add_membership(author_id, comm_id, "member").await;
148
149 h.client.get("/p/test/general/new").await;
150 h.client
151 .post_form(
152 "/p/test/general/new",
153 "title=Unknown+Mention&body=Hello+%40nonexistent",
154 )
155 .await;
156
157 let threads =
158 mt_db::queries::list_threads_in_category_paginated(&h.db, "test", "general", 10, 0)
159 .await
160 .unwrap();
161 let thread_id = threads[0].id;
162
163 let thread_url = format!("/p/test/general/{thread_id}");
164 let resp = h.client.get(&thread_url).await;
165
166 assert!(
167 resp.text.contains("@nonexistent"),
168 "Unknown mention should appear as plain text"
169 );
170 assert!(
171 !resp.text.contains("/p/test/u/nonexistent"),
172 "Unknown mention should NOT be a link"
173 );
174
175 let posts = mt_db::queries::list_posts_in_thread(&h.db, thread_id)
176 .await
177 .unwrap();
178 let post_id = posts[0].id;
179 let count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM post_mentions WHERE post_id = $1")
180 .bind(post_id)
181 .fetch_one(&h.db)
182 .await
183 .unwrap();
184 assert_eq!(count, 0, "No mention rows for unknown username");
185 }
186
187 #[tokio::test]
188 async fn mention_indicator_on_category_listing() {
189 let mut h = TestHarness::new().await;
190 let author_id = h.login_as("catmentionauth").await;
191 let comm_id = h.create_community("Test", "test").await;
192 let _cat_id = h.create_category(comm_id, "General", "general").await;
193 h.add_membership(author_id, comm_id, "member").await;
194
195 // Create the mentioned user via direct SQL (so author stays logged in)
196 let mentioned_id = uuid::Uuid::new_v4();
197 sqlx::query("INSERT INTO users (mnw_account_id, username, display_name) VALUES ($1, $2, $2)")
198 .bind(mentioned_id)
199 .bind("catmentionee")
200 .execute(&h.db)
201 .await
202 .unwrap();
203 h.add_membership(mentioned_id, comm_id, "member").await;
204
205 h.client.get("/p/test/general/new").await;
206 let resp = h
207 .client
208 .post_form(
209 "/p/test/general/new",
210 "title=Category+Mention+Test&body=Hey+%40catmentionee+check+this",
211 )
212 .await;
213 assert!(
214 resp.status.is_redirection(),
215 "Expected redirect, got {}",
216 resp.status
217 );
218
219 // Re-login as the mentioned user and view the category
220 h.client.get("/").await;
221 let body = serde_json::json!({
222 "user_id": mentioned_id.to_string(),
223 "username": "catmentionee",
224 });
225 h.client.post_json("/_test/login", &body.to_string()).await;
226
227 let resp = h.client.get("/p/test/general").await;
228 assert!(
229 resp.text.contains("badge-mention"),
230 "Expected badge-mention class in category listing. Body snippet: {}",
231 resp.text[resp.text.find("data-table").unwrap_or(0)..]
232 .chars()
233 .take(800)
234 .collect::<String>()
235 );
236 assert!(
237 resp.text.contains("mentioned"),
238 "Expected 'mentioned' class on tr element"
239 );
240 }
241
242 #[tokio::test]
243 async fn mention_indicator_on_tracked_page() {
244 let mut h = TestHarness::new().await;
245 let author_id = h.login_as("trackmentionauth").await;
246 let comm_id = h.create_community("Test", "test").await;
247 let _cat_id = h.create_category(comm_id, "General", "general").await;
248 h.add_membership(author_id, comm_id, "member").await;
249
250 // Create the mentioned user via direct SQL (so author stays logged in)
251 let mentioned_id = uuid::Uuid::new_v4();
252 sqlx::query("INSERT INTO users (mnw_account_id, username, display_name) VALUES ($1, $2, $2)")
253 .bind(mentioned_id)
254 .bind("trackmentionee")
255 .execute(&h.db)
256 .await
257 .unwrap();
258 h.add_membership(mentioned_id, comm_id, "member").await;
259
260 h.client.get("/p/test/general/new").await;
261 let resp = h
262 .client
263 .post_form(
264 "/p/test/general/new",
265 "title=Track+Mention+Test&body=Hello+%40trackmentionee",
266 )
267 .await;
268 assert!(
269 resp.status.is_redirection(),
270 "Expected redirect, got {}",
271 resp.status
272 );
273
274 let threads =
275 mt_db::queries::list_threads_in_category_paginated(&h.db, "test", "general", 10, 0)
276 .await
277 .unwrap();
278 let thread_id = threads[0].id;
279
280 mt_db::mutations::track_thread(&h.db, mentioned_id, thread_id)
281 .await
282 .unwrap();
283
284 // Log in as mentioned user
285 let body = serde_json::json!({
286 "user_id": mentioned_id.to_string(),
287 "username": "trackmentionee",
288 });
289 h.client.post_json("/_test/login", &body.to_string()).await;
290
291 let resp = h.client.get("/tracked").await;
292 assert!(
293 resp.text.contains("badge-mention"),
294 "Expected badge-mention in tracked page. Body snippet: {}",
295 resp.text[resp.text.find("data-table").unwrap_or(0)..]
296 .chars()
297 .take(800)
298 .collect::<String>()
299 );
300 assert!(
301 resp.text.contains("mentioned"),
302 "Expected 'mentioned' class on tr element in tracked page"
303 );
304 }
305