this repo has no description
1/*
2 * CONTENT WARNING
3 *
4 * This file contains explicit slurs and hateful language. We're sorry you have to see them.
5 *
6 * These words exist here for one reason: to ensure our moderation system correctly blocks them.
7 * We can't verify the filter catches the n-word without testing against the actual word.
8 * Euphemisms wouldn't prove the protection works.
9 *
10 * If reading this file has caused you distress, please know:
11 * - you are valued and welcome in this community
12 * - these words do not reflect the views of this project or its contributors
13 * - we maintain this code precisely because we believe everyone deserves an experience on the web that is free from this kinda language
14*/
15
16mod common;
17mod helpers;
18use common::*;
19use helpers::*;
20use reqwest::StatusCode;
21use serde_json::json;
22
23#[tokio::test]
24async fn test_handle_with_slur_rejected() {
25 let client = client();
26 let timestamp = chrono::Utc::now().timestamp_millis();
27 let offensive_handle = format!("nigger{}", timestamp);
28
29 let create_payload = json!({
30 "handle": offensive_handle,
31 "email": format!("test{}@example.com", timestamp),
32 "password": "TestPassword123!"
33 });
34
35 let res = client
36 .post(format!(
37 "{}/xrpc/com.atproto.server.createAccount",
38 base_url().await
39 ))
40 .json(&create_payload)
41 .send()
42 .await
43 .expect("Request failed");
44
45 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
46 let body: serde_json::Value = res.json().await.unwrap();
47 assert_eq!(body["error"], "InvalidHandle");
48 assert!(body["message"]
49 .as_str()
50 .unwrap_or("")
51 .contains("Inappropriate language"));
52}
53
54#[tokio::test]
55async fn test_handle_with_normalized_slur_rejected() {
56 let client = client();
57 let timestamp = chrono::Utc::now().timestamp_millis();
58 let offensive_handle = format!("n-i-g-g-e-r{}", timestamp);
59
60 let create_payload = json!({
61 "handle": offensive_handle,
62 "email": format!("test{}@example.com", timestamp),
63 "password": "TestPassword123!"
64 });
65
66 let res = client
67 .post(format!(
68 "{}/xrpc/com.atproto.server.createAccount",
69 base_url().await
70 ))
71 .json(&create_payload)
72 .send()
73 .await
74 .expect("Request failed");
75
76 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
77 let body: serde_json::Value = res.json().await.unwrap();
78 assert_eq!(body["error"], "InvalidHandle");
79}
80
81#[tokio::test]
82async fn test_handle_update_with_slur_rejected() {
83 let client = client();
84 let (_, jwt) = setup_new_user("handleupdate").await;
85
86 let update_payload = json!({
87 "handle": "faggots"
88 });
89
90 let res = client
91 .post(format!(
92 "{}/xrpc/com.atproto.identity.updateHandle",
93 base_url().await
94 ))
95 .bearer_auth(&jwt)
96 .json(&update_payload)
97 .send()
98 .await
99 .expect("Request failed");
100
101 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
102 let body: serde_json::Value = res.json().await.unwrap();
103 assert_eq!(body["error"], "InvalidHandle");
104}
105
106#[tokio::test]
107async fn test_profile_displayname_with_slur_rejected() {
108 let client = client();
109 let (did, jwt) = setup_new_user("profileslur").await;
110
111 let profile = json!({
112 "repo": did,
113 "collection": "app.bsky.actor.profile",
114 "rkey": "self",
115 "record": {
116 "$type": "app.bsky.actor.profile",
117 "displayName": "I am a kike"
118 }
119 });
120
121 let res = client
122 .post(format!(
123 "{}/xrpc/com.atproto.repo.putRecord",
124 base_url().await
125 ))
126 .bearer_auth(&jwt)
127 .json(&profile)
128 .send()
129 .await
130 .expect("Request failed");
131
132 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
133 let body: serde_json::Value = res.json().await.unwrap();
134 assert_eq!(body["error"], "InvalidRecord");
135}
136
137#[tokio::test]
138async fn test_profile_description_with_slur_rejected() {
139 let client = client();
140 let (did, jwt) = setup_new_user("profiledesc").await;
141
142 let profile = json!({
143 "repo": did,
144 "collection": "app.bsky.actor.profile",
145 "rkey": "self",
146 "record": {
147 "$type": "app.bsky.actor.profile",
148 "displayName": "Normal Name",
149 "description": "I hate all chinks"
150 }
151 });
152
153 let res = client
154 .post(format!(
155 "{}/xrpc/com.atproto.repo.putRecord",
156 base_url().await
157 ))
158 .bearer_auth(&jwt)
159 .json(&profile)
160 .send()
161 .await
162 .expect("Request failed");
163
164 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
165 let body: serde_json::Value = res.json().await.unwrap();
166 assert_eq!(body["error"], "InvalidRecord");
167}
168
169#[tokio::test]
170async fn test_clean_content_allowed() {
171 let client = client();
172 let (did, jwt) = setup_new_user("cleanpost").await;
173
174 let post = json!({
175 "repo": did,
176 "collection": "app.bsky.feed.post",
177 "record": {
178 "$type": "app.bsky.feed.post",
179 "text": "This is a perfectly normal post about coding and technology!",
180 "createdAt": chrono::Utc::now().to_rfc3339()
181 }
182 });
183
184 let res = client
185 .post(format!(
186 "{}/xrpc/com.atproto.repo.createRecord",
187 base_url().await
188 ))
189 .bearer_auth(&jwt)
190 .json(&post)
191 .send()
192 .await
193 .expect("Request failed");
194
195 assert_eq!(res.status(), StatusCode::OK);
196}