Skip to main content

max / makenotwork

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