Skip to main content

max / makenotwork

4.0 KB · 144 lines History Blame Raw
1 //! Broadcast workflow tests: creator sends email to followers.
2 //!
3 //! Note: broadcast validation errors return 200 with error HTML (HTMX pattern),
4 //! so we check body content for "form-status error" instead of status codes.
5
6 use crate::harness::TestHarness;
7
8 #[tokio::test]
9 async fn broadcast_requires_auth() {
10 let mut h = TestHarness::new().await;
11
12 let resp = h
13 .client
14 .post_form(
15 "/api/broadcast",
16 "subject=Hello&body=Test+broadcast+message",
17 )
18 .await;
19 assert!(
20 resp.status.is_client_error() || resp.status.is_redirection(),
21 "Unauthenticated broadcast should be rejected: {} {}",
22 resp.status,
23 resp.text
24 );
25 }
26
27 #[tokio::test]
28 async fn broadcast_requires_creator() {
29 let mut h = TestHarness::new().await;
30 let _user_id = h
31 .signup("bcastuser", "bcastuser@test.com", "password123")
32 .await;
33
34 // Regular user (not a creator), returns 200 with error HTML
35 let resp = h
36 .client
37 .post_form(
38 "/api/broadcast",
39 "subject=Hello&body=Test+broadcast+message",
40 )
41 .await;
42 assert!(
43 resp.text.contains("form-status error"),
44 "Non-creator broadcast should return error: {}",
45 resp.text
46 );
47 }
48
49 #[tokio::test]
50 async fn broadcast_empty_subject_rejected() {
51 let mut h = TestHarness::new().await;
52 let user_id = h
53 .signup("bcastempty", "bcastempty@test.com", "password123")
54 .await;
55 h.grant_creator(user_id).await;
56 h.client.post_form("/logout", "").await;
57 h.login("bcastempty", "password123").await;
58
59 let resp = h
60 .client
61 .post_form("/api/broadcast", "subject=&body=Some+body+text")
62 .await;
63 assert!(
64 resp.text.contains("form-status error"),
65 "Empty subject broadcast should return error: {}",
66 resp.text
67 );
68 }
69
70 #[tokio::test]
71 async fn broadcast_empty_body_rejected() {
72 let mut h = TestHarness::new().await;
73 let user_id = h
74 .signup("bcastnobody", "bcastnobody@test.com", "password123")
75 .await;
76 h.grant_creator(user_id).await;
77 h.client.post_form("/logout", "").await;
78 h.login("bcastnobody", "password123").await;
79
80 let resp = h
81 .client
82 .post_form("/api/broadcast", "subject=Hello&body=")
83 .await;
84 assert!(
85 resp.text.contains("form-status error"),
86 "Empty body broadcast should return error: {}",
87 resp.text
88 );
89 }
90
91 #[tokio::test]
92 async fn broadcast_succeeds_for_creator() {
93 let mut h = TestHarness::new().await;
94 let user_id = h.signup("bcastok", "bcastok@test.com", "password123").await;
95 h.grant_creator(user_id).await;
96 h.client.post_form("/logout", "").await;
97 h.login("bcastok", "password123").await;
98
99 let resp = h
100 .client
101 .post_form(
102 "/api/broadcast",
103 "subject=Test+Broadcast&body=Hello+followers+this+is+a+test",
104 )
105 .await;
106 assert!(
107 resp.status.is_success(),
108 "Creator broadcast should succeed: {} {}",
109 resp.status,
110 resp.text
111 );
112 // Success response should contain "form-status success", not error
113 assert!(
114 !resp.text.contains("form-status error"),
115 "Successful broadcast should not contain error: {}",
116 resp.text
117 );
118 }
119
120 #[tokio::test]
121 async fn broadcast_subject_too_long_rejected() {
122 let mut h = TestHarness::new().await;
123 let user_id = h
124 .signup("bcastlong", "bcastlong@test.com", "password123")
125 .await;
126 h.grant_creator(user_id).await;
127 h.client.post_form("/logout", "").await;
128 h.login("bcastlong", "password123").await;
129
130 let long_subject = "a".repeat(201);
131 let resp = h
132 .client
133 .post_form(
134 "/api/broadcast",
135 &format!("subject={long_subject}&body=Some+body"),
136 )
137 .await;
138 assert!(
139 resp.text.contains("form-status error"),
140 "Subject >200 chars should return error: {}",
141 resp.text
142 );
143 }
144