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

This commit is contained in:
SCOPEDD committed 2026-09-30 22:56:38 -04:00
1 parent ce49447b6e
commit 60edc99780
58 files changed
+3533 -1375

No files matched your search

+35 -9
View File
@@ -21,14 +21,20 @@ async fn fixture() -> Fixture {
for n in ["Alex", "Steve", "Mia"] {
t.call("POST", "/api/admin/users", Some(&admin), Some(json!({"username": n, "password": "password123"}))).await;
}
let (alex, steve, mia) = (t.login("Alex", "password123").await, t.login("Steve", "password123").await, t.login("Mia", "password123").await);
let (alex, steve, mia) =
(t.login("Alex", "password123").await, t.login("Steve", "password123").await, t.login("Mia", "password123").await);
let (alex_uuid, steve_uuid) = (t.uuid("Alex").await, t.uuid("Steve").await);
let (_, srv) = t.call("POST", "/api/admin/servers", Some(&admin), Some(json!({"name": "SMP", "instance_id": "smp"}))).await;
let sid = srv["server"]["id"].as_i64().unwrap();
let server = srv["token"].as_str().unwrap().to_string();
let (_, g) = t.call("POST", "/api/v1/guilds", Some(&alex), Some(json!({"instance_id": "smp", "name": "Iron", "tag": "IRON"}))).await;
let gid = g["id"].as_str().unwrap().to_string();
sqlx::query("INSERT INTO guild_members (guild_id, uuid, name, role, joined_at) VALUES (?, ?, 'Steve', 'member', '2026-01-01')").bind(&gid).bind(&steve_uuid).execute(&t.db).await.unwrap();
sqlx::query("INSERT INTO guild_members (guild_id, uuid, name, role, joined_at) VALUES (?, ?, 'Steve', 'member', '2026-01-01')")
.bind(&gid)
.bind(&steve_uuid)
.execute(&t.db)
.await
.unwrap();
// Mia leads a second guild.
t.call("POST", "/api/v1/guilds", Some(&mia), Some(json!({"instance_id": "smp", "name": "Void", "tag": "VOID"}))).await;
Fixture { t, server, sid, alex, steve, alex_uuid, steve_uuid, gid }
@@ -39,7 +45,12 @@ impl Fixture {
self.t.call("POST", &format!("/api/server/v1/{path}"), Some(&self.server), Some(body)).await
}
async fn guild_balance(&self) -> f64 {
sqlx::query_scalar("SELECT COALESCE((SELECT balance FROM guild_wallets WHERE guild_id = ? AND server_id = ?), 0)").bind(&self.gid).bind(self.sid).fetch_one(&self.t.db).await.unwrap()
sqlx::query_scalar("SELECT COALESCE((SELECT balance FROM guild_wallets WHERE guild_id = ? AND server_id = ?), 0)")
.bind(&self.gid)
.bind(self.sid)
.fetch_one(&self.t.db)
.await
.unwrap()
}
}
@@ -87,12 +98,18 @@ async fn bank_deposits_withdrawals_and_roles() {
#[tokio::test]
async fn shop_sales_and_guild_payments() {
let f = fixture().await;
let credit = json!({"operation_id": "sale-1", "uuid": f.steve_uuid, "username": "Steve", "amount": 64.0, "description": "64x Cobblestone"});
let credit =
json!({"operation_id": "sale-1", "uuid": f.steve_uuid, "username": "Steve", "amount": 64.0, "description": "64x Cobblestone"});
let (s, r) = f.post("guilds/bank/credit", credit.clone()).await;
assert_eq!(s, StatusCode::OK, "{r}");
assert_eq!(f.post("guilds/bank/credit", credit).await.1, r);
assert_eq!(f.guild_balance().await, 64.0);
let (_, nobody) = f.post("guilds/bank/credit", json!({"operation_id": "sale-2", "uuid": "00000000-0000-0000-0000-000000000009", "username": "X", "amount": 5.0})).await;
let (_, nobody) = f
.post(
"guilds/bank/credit",
json!({"operation_id": "sale-2", "uuid": "00000000-0000-0000-0000-000000000009", "username": "X", "amount": 5.0}),
)
.await;
assert!(nobody["error"].as_str().unwrap().contains("not in a guild"));
let pay = |op: &str, who: &str, tag: &str, amount: f64| json!({"operation_id": op, "uuid": who, "to_tag": tag, "amount": amount});
@@ -103,7 +120,8 @@ async fn shop_sales_and_guild_payments() {
let (s, r) = f.post("guilds/bank/pay", pay("p5", &f.alex_uuid, "void", 24.0)).await;
assert_eq!(s, StatusCode::OK, "{r}");
assert_eq!(r["balance"], 40.0);
let void_balance: f64 = sqlx::query_scalar("SELECT balance FROM guild_wallets WHERE guild_id <> ?").bind(&f.gid).fetch_one(&f.t.db).await.unwrap();
let void_balance: f64 =
sqlx::query_scalar("SELECT balance FROM guild_wallets WHERE guild_id <> ?").bind(&f.gid).fetch_one(&f.t.db).await.unwrap();
assert_eq!(void_balance, 24.0);
let kinds: Vec<String> = sqlx::query_scalar("SELECT kind FROM guild_wallet_transactions ORDER BY id").fetch_all(&f.t.db).await.unwrap();
assert_eq!(kinds, ["sale", "transfer_out", "transfer_in"]);
@@ -126,7 +144,13 @@ async fn guild_market_listings_and_purchases() {
// Mia's guild buys it with guild money: she's an officer but the bank is empty first.
let mia_uuid = f.t.uuid("Mia").await;
let buy = |op: &str| json!({"operation_id": op, "listing_id": listing, "buyer_uuid": mia_uuid, "buyer_name": "Mia", "as_guild": true});
sqlx::query("INSERT INTO guild_wallets (server_id, guild_id, balance, updated_at) SELECT ?, id, 50, 'now' FROM guilds WHERE tag = 'VOID'").bind(f.sid).execute(&f.t.db).await.unwrap();
sqlx::query(
"INSERT INTO guild_wallets (server_id, guild_id, balance, updated_at) SELECT ?, id, 50, 'now' FROM guilds WHERE tag = 'VOID'",
)
.bind(f.sid)
.execute(&f.t.db)
.await
.unwrap();
let (s, e) = f.post("economy/market/buy", buy("b1")).await;
assert_eq!(s, StatusCode::BAD_REQUEST, "{e}");
let still: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM server_market").fetch_one(&f.t.db).await.unwrap();
@@ -136,7 +160,8 @@ async fn guild_market_listings_and_purchases() {
assert_eq!(s, StatusCode::OK, "{r}");
assert_eq!(r["new_balance"], 380.0);
assert_eq!(f.guild_balance().await, 120.0, "the sale is paid into the listing guild's bank");
let alex_balance: Option<f64> = sqlx::query_scalar("SELECT balance FROM server_economy WHERE uuid = ?").bind(&f.alex_uuid).fetch_optional(&f.t.db).await.unwrap();
let alex_balance: Option<f64> =
sqlx::query_scalar("SELECT balance FROM server_economy WHERE uuid = ?").bind(&f.alex_uuid).fetch_optional(&f.t.db).await.unwrap();
assert!(alex_balance.is_none(), "the lister is not paid personally");
let kinds: Vec<String> = sqlx::query_scalar("SELECT kind FROM guild_wallet_transactions ORDER BY id").fetch_all(&f.t.db).await.unwrap();
assert_eq!(kinds, ["purchase", "sale"]);
@@ -150,6 +175,7 @@ async fn guild_market_listings_and_purchases() {
let (s, r) = f.post("economy/market/buy", pay).await;
assert_eq!(s, StatusCode::OK, "{r}");
assert_eq!(r["new_balance"], 880.0);
let steve_balance: f64 = sqlx::query_scalar("SELECT balance FROM server_economy WHERE uuid = ?").bind(&f.steve_uuid).fetch_one(&f.t.db).await.unwrap();
let steve_balance: f64 =
sqlx::query_scalar("SELECT balance FROM server_economy WHERE uuid = ?").bind(&f.steve_uuid).fetch_one(&f.t.db).await.unwrap();
assert_eq!(steve_balance, 1120.0);
}