Fix Rust formatting
Server integrations / Paper and protocol tests (push) Failing after 20s
Server integrations / fabric / 1.20.1 (push) Failing after 11s
Server integrations / fabric / 1.21.1 (push) Failing after 14s
Server integrations / fabric / 26.1.2 (push) Failing after 17s
Server integrations / fabric / 26.2 (push) Failing after 12s
Server integrations / fabric / 26.3 (push) Failing after 6s
Server integrations / forge / 1.20.1 (push) Failing after 6s
Server integrations / forge / 1.21.1 (push) Failing after 8s
Server integrations / forge / 26.1.2 (push) Failing after 8s
Server integrations / forge / 26.2 (push) Failing after 8s
Server integrations / forge / 26.3 (push) Failing after 7s
CI / Web UIs (type-check + build) (panel/web) (push) Canceled after 0s
CI / Launcher (Windows build check) (push) Canceled after 2m53s
CI / Real installs (Mojang, Fabric, Quilt, Forge, NeoForge) (push) Canceled after 0s
CI / Docker image builds (push) Canceled after 0s
CI / Rust (fmt, clippy, tests) (push) Canceled after 1m22s
CI / Web UIs (type-check + build) (launcher) (push) Canceled after 1m27s
Server integrations / Paper and protocol tests (push) Failing after 20s
Server integrations / fabric / 1.20.1 (push) Failing after 11s
Server integrations / fabric / 1.21.1 (push) Failing after 14s
Server integrations / fabric / 26.1.2 (push) Failing after 17s
Server integrations / fabric / 26.2 (push) Failing after 12s
Server integrations / fabric / 26.3 (push) Failing after 6s
Server integrations / forge / 1.20.1 (push) Failing after 6s
Server integrations / forge / 1.21.1 (push) Failing after 8s
Server integrations / forge / 26.1.2 (push) Failing after 8s
Server integrations / forge / 26.2 (push) Failing after 8s
Server integrations / forge / 26.3 (push) Failing after 7s
CI / Web UIs (type-check + build) (panel/web) (push) Canceled after 0s
CI / Launcher (Windows build check) (push) Canceled after 2m53s
CI / Real installs (Mojang, Fabric, Quilt, Forge, NeoForge) (push) Canceled after 0s
CI / Docker image builds (push) Canceled after 0s
CI / Rust (fmt, clippy, tests) (push) Canceled after 1m22s
CI / Web UIs (type-check + build) (launcher) (push) Canceled after 1m27s
This commit is contained in:
1 parent
ce49447b6e
commit
60edc99780
58 files changed
+3533
-1375
No files matched your search
@@ -20,21 +20,32 @@ async fn emails_use_templates_audiences_and_opt_outs() {
|
||||
assert_eq!(t.call("PUT", "/api/admin/email/templates", Some(&admin), Some(ok)).await.0, StatusCode::OK);
|
||||
|
||||
// Placeholders fill per player, and the HTML is branded and has an unsubscribe link.
|
||||
let (s, p) = t.call("POST", "/api/admin/email/preview", Some(&admin), Some(json!({"subject": "Hi {player}", "body": "Hello **{player}**\n\n[button: Go]({panel_url})"}))).await;
|
||||
let (s, p) = t
|
||||
.call(
|
||||
"POST",
|
||||
"/api/admin/email/preview",
|
||||
Some(&admin),
|
||||
Some(json!({"subject": "Hi {player}", "body": "Hello **{player}**\n\n[button: Go]({panel_url})"})),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(s, StatusCode::OK, "{p}");
|
||||
assert_eq!(p["subject"], "Hi admin");
|
||||
assert!(p["html"].as_str().unwrap().contains("<strong>admin</strong>") && p["html"].as_str().unwrap().contains("Unsubscribe"));
|
||||
assert!(p["text"].as_str().unwrap().contains("/api/v1/email/unsubscribe?u="));
|
||||
|
||||
// Only active players with an email count.
|
||||
let count = |a: Value| { let (t, admin) = (&t, admin.clone()); async move { t.call("POST", "/api/admin/email/audience", Some(&admin), Some(json!({"audience": a}))).await.1 } };
|
||||
let count = |a: Value| {
|
||||
let (t, admin) = (&t, admin.clone());
|
||||
async move { t.call("POST", "/api/admin/email/audience", Some(&admin), Some(json!({"audience": a}))).await.1 }
|
||||
};
|
||||
assert_eq!(count(json!({"kind": "all"})).await["count"], 2, "Steve and Alex have an address; Notch and admin don't");
|
||||
assert_eq!(count(json!({"kind": "players", "names": ["steve", "nobody"]})).await["count"], 1);
|
||||
|
||||
// Opting out through the link removes a player from marketing mail, but not from account notices.
|
||||
let steve = t.uuid("Steve").await;
|
||||
let token = {
|
||||
let secret: String = sqlx::query_scalar("SELECT value FROM kv WHERE key = 'email_unsubscribe_secret'").fetch_one(&t.db).await.unwrap();
|
||||
let secret: String =
|
||||
sqlx::query_scalar("SELECT value FROM kv WHERE key = 'email_unsubscribe_secret'").fetch_one(&t.db).await.unwrap();
|
||||
let secret = secret.trim_matches('"').to_string();
|
||||
use sha2::{Digest, Sha256};
|
||||
Sha256::digest(format!("{secret}:{steve}").as_bytes()).iter().take(16).map(|b| format!("{b:02x}")).collect::<String>()
|
||||
@@ -44,15 +55,21 @@ async fn emails_use_templates_audiences_and_opt_outs() {
|
||||
assert_eq!(count(json!({"kind": "all"})).await["count"], 2, "a wrong token changes nothing");
|
||||
t.fetch(&format!("/api/v1/email/unsubscribe?u={steve}&t={token}")).await;
|
||||
assert_eq!(count(json!({"kind": "all"})).await["count"], 1);
|
||||
let (_, important) = t.call("POST", "/api/admin/email/audience", Some(&admin), Some(json!({"audience": {"kind": "all"}, "important": true}))).await;
|
||||
let (_, important) =
|
||||
t.call("POST", "/api/admin/email/audience", Some(&admin), Some(json!({"audience": {"kind": "all"}, "important": true}))).await;
|
||||
assert_eq!(important["count"], 2);
|
||||
|
||||
// Without SMTP configured, a send is queued but each message fails with a clear reason in the log.
|
||||
let (s, sent) = t.call("POST", "/api/admin/email/send", Some(&admin), Some(json!({"subject": "Hi", "body": "Hello", "audience": {"kind": "all"}}))).await;
|
||||
let (s, sent) = t
|
||||
.call("POST", "/api/admin/email/send", Some(&admin), Some(json!({"subject": "Hi", "body": "Hello", "audience": {"kind": "all"}})))
|
||||
.await;
|
||||
assert_eq!(s, StatusCode::OK, "{sent}");
|
||||
for _ in 0..40 {
|
||||
let (_, all) = t.call("GET", "/api/admin/email", Some(&admin), None).await;
|
||||
if all["log"][0]["failed"] == 1 { assert!(all["log"][0]["last_error"].as_str().unwrap().contains("Resend")); return; }
|
||||
if all["log"][0]["failed"] == 1 {
|
||||
assert!(all["log"][0]["last_error"].as_str().unwrap().contains("Resend"));
|
||||
return;
|
||||
}
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
}
|
||||
panic!("the send was never logged");
|
||||
|
||||
Reference in new issue
Block a user