Skip to main content

max / makenotwork

6.7 KB · 200 lines History Blame Raw
1 use crate::harness::TestHarness;
2
3 #[tokio::test]
4 async fn profile_page_shows_user_info() {
5 let mut h = TestHarness::new().await;
6 let user_id = h.login_as("profileuser").await;
7 let comm_id = h.create_community("TestCommunity", "test-comm").await;
8 h.create_category(comm_id, "General", "general").await;
9 h.add_membership(user_id, comm_id, "member").await;
10
11 let resp = h.client.get("/p/test-comm/u/profileuser").await;
12 assert_eq!(resp.status.as_u16(), 200, "profile page should load");
13 assert!(resp.text.contains("profileuser"), "should show username");
14 assert!(resp.text.contains("member"), "should show role badge");
15 assert!(resp.text.contains("Joined"), "should show join date");
16 }
17
18 #[tokio::test]
19 async fn profile_page_shows_activity() {
20 let mut h = TestHarness::new().await;
21 let user_id = h.login_as("activeuser").await;
22 let comm_id = h.create_community("ActivityComm", "activity-comm").await;
23 let cat_id = h.create_category(comm_id, "General", "general").await;
24 h.add_membership(user_id, comm_id, "member").await;
25
26 // Create a thread (user is thread author)
27 let thread_id = h
28 .create_thread_with_post(cat_id, user_id, "My Thread", "Hello world")
29 .await;
30
31 // Create a reply in another thread
32 let thread_id_2 = h
33 .create_thread_with_post(cat_id, user_id, "Another Thread", "Second post")
34 .await;
35 mt_db::mutations::create_post(&h.db, thread_id_2, user_id, "A reply", "<p>A reply</p>")
36 .await
37 .unwrap();
38
39 let resp = h.client.get("/p/activity-comm/u/activeuser").await;
40 assert_eq!(resp.status.as_u16(), 200);
41 assert!(
42 resp.text.contains("My Thread"),
43 "should list thread activity"
44 );
45 assert!(
46 resp.text.contains("Another Thread"),
47 "should list reply activity"
48 );
49
50 // Verify thread_id link is present
51 assert!(
52 resp.text.contains(&thread_id.to_string()),
53 "should link to thread"
54 );
55 }
56
57 #[tokio::test]
58 async fn profile_nonmember_returns_404() {
59 let mut h = TestHarness::new().await;
60 h.login_as("outsider").await;
61 let _comm_id = h.create_community("ClosedComm", "closed-comm").await;
62
63 // User exists but is not a member
64 let resp = h.client.get("/p/closed-comm/u/outsider").await;
65 assert_eq!(resp.status.as_u16(), 404, "non-member should get 404");
66 }
67
68 #[tokio::test]
69 async fn profile_nonexistent_user_404() {
70 let mut h = TestHarness::new().await;
71 h.login_as("someuser").await;
72 let _comm_id = h.create_community("SomeComm", "some-comm").await;
73
74 let resp = h.client.get("/p/some-comm/u/nobodyhere").await;
75 assert_eq!(resp.status.as_u16(), 404, "nonexistent user should get 404");
76 }
77
78 #[tokio::test]
79 async fn profile_suspended_community_blocked() {
80 let mut h = TestHarness::new().await;
81 let user_id = h.login_as("suspendedfan").await;
82 let comm_id = h.create_community("SuspendedComm", "suspended-comm").await;
83 h.add_membership(user_id, comm_id, "member").await;
84
85 // Suspend the community
86 sqlx::query("UPDATE communities SET suspended_at = now() WHERE id = $1")
87 .bind(comm_id)
88 .execute(&h.db)
89 .await
90 .unwrap();
91
92 let resp = h.client.get("/p/suspended-comm/u/suspendedfan").await;
93 assert_eq!(
94 resp.status.as_u16(),
95 403,
96 "suspended community should return 403"
97 );
98 }
99
100 #[tokio::test]
101 async fn api_summary_requires_auth() {
102 let mut h = TestHarness::new().await;
103 // Don't log in, make unauthenticated request
104 h.client.get("/").await; // establish session
105
106 let user_id = uuid::Uuid::new_v4();
107 let resp = h.client.get(&format!("/api/user/{user_id}/summary")).await;
108 assert_eq!(resp.status.as_u16(), 401, "unauthenticated should get 401");
109 }
110
111 #[tokio::test]
112 async fn api_summary_returns_memberships() {
113 let mut h = TestHarness::new().await;
114 let user_id = h.login_as("summaryuser").await;
115 let comm_id = h.create_community("SummaryComm", "summary-comm").await;
116 h.add_membership(user_id, comm_id, "member").await;
117
118 let resp = h.client.get(&format!("/api/user/{user_id}/summary")).await;
119 assert_eq!(resp.status.as_u16(), 200, "should return 200");
120
121 let json: serde_json::Value = resp.json();
122 let memberships = json["memberships"].as_array().unwrap();
123 assert_eq!(memberships.len(), 1, "should have one membership");
124 assert_eq!(memberships[0]["community_name"], "SummaryComm");
125 assert_eq!(memberships[0]["community_slug"], "summary-comm");
126 assert_eq!(memberships[0]["role"], "member");
127 }
128
129 #[tokio::test]
130 async fn api_summary_only_own_data() {
131 let mut h = TestHarness::new().await;
132 let _user_id = h.login_as("snoop").await;
133
134 // Try to access another user's summary
135 let other_id = uuid::Uuid::new_v4();
136 let resp = h.client.get(&format!("/api/user/{other_id}/summary")).await;
137 assert_eq!(
138 resp.status.as_u16(),
139 403,
140 "accessing other user's data should return 403"
141 );
142 }
143
144 #[tokio::test]
145 async fn profile_shows_endorsement_count() {
146 let mut h = TestHarness::new().await;
147 let author_id = h.login_as("endorsedauthor").await;
148 let comm_id = h.create_community("EndorseComm", "endorse-comm").await;
149 let cat_id = h.create_category(comm_id, "General", "general").await;
150 h.add_membership(author_id, comm_id, "member").await;
151
152 // Author creates a thread with a post
153 let thread_id = h
154 .create_thread_with_post(cat_id, author_id, "Great Thread", "Great content")
155 .await;
156
157 // Get the first post ID
158 let posts = mt_db::queries::list_posts_in_thread(&h.db, thread_id)
159 .await
160 .unwrap();
161 let post_id = posts[0].id;
162
163 // Another user endorses the post
164 let endorser_id = h.login_as("endorser1").await;
165 h.add_membership(endorser_id, comm_id, "member").await;
166 mt_db::mutations::toggle_endorsement(&h.db, post_id, endorser_id)
167 .await
168 .unwrap();
169
170 // Check the author's profile shows endorsement count
171 let resp = h.client.get("/p/endorse-comm/u/endorsedauthor").await;
172 assert_eq!(resp.status.as_u16(), 200);
173 assert!(
174 resp.text.contains("1 endorsement received"),
175 "Profile should show endorsement count. Body: {}",
176 &resp.text[..500.min(resp.text.len())]
177 );
178 }
179
180 #[tokio::test]
181 async fn tracking_info_page_loads() {
182 let mut h = TestHarness::new().await;
183 h.login_as("infouser").await;
184
185 let resp = h.client.get("/about/tracking").await;
186 assert_eq!(resp.status.as_u16(), 200);
187 assert!(
188 resp.text.contains("How Tracking Works"),
189 "Should show tracking info heading"
190 );
191 assert!(
192 resp.text.contains("localStorage"),
193 "Should explain localStorage tracking"
194 );
195 assert!(
196 resp.text.contains("No third-party"),
197 "Should mention no third-party tracking"
198 );
199 }
200