Skip to main content

max / makenotwork

4.0 KB · 134 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, resp.text
23 );
24 }
25
26 #[tokio::test]
27 async fn broadcast_requires_creator() {
28 let mut h = TestHarness::new().await;
29 let _user_id = h.signup("bcastuser", "bcastuser@test.com", "password123").await;
30
31 // Regular user (not a creator) — returns 200 with error HTML
32 let resp = h
33 .client
34 .post_form(
35 "/api/broadcast",
36 "subject=Hello&body=Test+broadcast+message",
37 )
38 .await;
39 assert!(
40 resp.text.contains("form-status error"),
41 "Non-creator broadcast should return error: {}",
42 resp.text
43 );
44 }
45
46 #[tokio::test]
47 async fn broadcast_empty_subject_rejected() {
48 let mut h = TestHarness::new().await;
49 let user_id = h.signup("bcastempty", "bcastempty@test.com", "password123").await;
50 h.grant_creator(user_id).await;
51 h.client.post_form("/logout", "").await;
52 h.login("bcastempty", "password123").await;
53
54 let resp = h
55 .client
56 .post_form("/api/broadcast", "subject=&body=Some+body+text")
57 .await;
58 assert!(
59 resp.text.contains("form-status error"),
60 "Empty subject broadcast should return error: {}",
61 resp.text
62 );
63 }
64
65 #[tokio::test]
66 async fn broadcast_empty_body_rejected() {
67 let mut h = TestHarness::new().await;
68 let user_id = h.signup("bcastnobody", "bcastnobody@test.com", "password123").await;
69 h.grant_creator(user_id).await;
70 h.client.post_form("/logout", "").await;
71 h.login("bcastnobody", "password123").await;
72
73 let resp = h
74 .client
75 .post_form("/api/broadcast", "subject=Hello&body=")
76 .await;
77 assert!(
78 resp.text.contains("form-status error"),
79 "Empty body broadcast should return error: {}",
80 resp.text
81 );
82 }
83
84 #[tokio::test]
85 async fn broadcast_succeeds_for_creator() {
86 let mut h = TestHarness::new().await;
87 let user_id = h.signup("bcastok", "bcastok@test.com", "password123").await;
88 h.grant_creator(user_id).await;
89 h.client.post_form("/logout", "").await;
90 h.login("bcastok", "password123").await;
91
92 let resp = h
93 .client
94 .post_form(
95 "/api/broadcast",
96 "subject=Test+Broadcast&body=Hello+followers+this+is+a+test",
97 )
98 .await;
99 assert!(
100 resp.status.is_success(),
101 "Creator broadcast should succeed: {} {}",
102 resp.status, resp.text
103 );
104 // Success response should contain "form-status success", not error
105 assert!(
106 !resp.text.contains("form-status error"),
107 "Successful broadcast should not contain error: {}",
108 resp.text
109 );
110 }
111
112 #[tokio::test]
113 async fn broadcast_subject_too_long_rejected() {
114 let mut h = TestHarness::new().await;
115 let user_id = h.signup("bcastlong", "bcastlong@test.com", "password123").await;
116 h.grant_creator(user_id).await;
117 h.client.post_form("/logout", "").await;
118 h.login("bcastlong", "password123").await;
119
120 let long_subject = "a".repeat(201);
121 let resp = h
122 .client
123 .post_form(
124 "/api/broadcast",
125 &format!("subject={}&body=Some+body", long_subject),
126 )
127 .await;
128 assert!(
129 resp.text.contains("form-status error"),
130 "Subject >200 chars should return error: {}",
131 resp.text
132 );
133 }
134