From dee9275497606d23449cc35e73fb89a8df384b79 Mon Sep 17 00:00:00 2001 From: npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Date: Sat, 1 Aug 2026 14:07:52 -0400 Subject: [PATCH] test(db): cover SQLite relay invite claims Signed-off-by: npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> --- crates/buzz-db/src/sqlite.rs | 87 ++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/crates/buzz-db/src/sqlite.rs b/crates/buzz-db/src/sqlite.rs index 26e62da4e..b18a61e36 100644 --- a/crates/buzz-db/src/sqlite.rs +++ b/crates/buzz-db/src/sqlite.rs @@ -2960,6 +2960,93 @@ mod tests { assert_eq!((summary.reply_count, summary.descendant_count), (0, 0)); } + #[tokio::test] + async fn relay_invites_preserve_claim_scope_limits_policy_and_retention() { + let pool = connect(":memory:").await.unwrap(); + let community = ensure_configured_community(&pool, "invites.local") + .await + .unwrap() + .id; + let foreign = ensure_configured_community(&pool, "foreign-invites.local") + .await + .unwrap() + .id; + let now = chrono::Utc::now().timestamp(); + let bounded = [7_u8; 32]; + sqlx::query("INSERT INTO relay_invites (community_id,id,token_hash,max_uses,expires_at,created_by) VALUES (?1,?2,?3,1,?4,'owner')") + .bind(community.as_uuid().to_string()).bind(Uuid::new_v4().to_string()).bind(bounded.as_slice()).bind(now + 3600).execute(&pool).await.unwrap(); + + assert_eq!( + claim_relay_invite(&pool, foreign, &bounded, "alice", None) + .await + .unwrap(), + crate::relay_invite::ClaimOutcome::Invalid + ); + assert_eq!( + claim_relay_invite(&pool, community, &bounded, "alice", Some("v1")) + .await + .unwrap(), + crate::relay_invite::ClaimOutcome::Joined { + use_count: 1, + uses_remaining: Some(0) + } + ); + assert_eq!( + claim_relay_invite(&pool, community, &bounded, "alice", Some("v1")) + .await + .unwrap(), + crate::relay_invite::ClaimOutcome::AlreadyMember { + use_count: 1, + uses_remaining: Some(0) + } + ); + assert_eq!( + claim_relay_invite(&pool, community, &bounded, "bob", None) + .await + .unwrap(), + crate::relay_invite::ClaimOutcome::Exhausted + ); + assert_eq!(sqlx::query_scalar::<_, i64>("SELECT count(*) FROM join_policy_acceptances WHERE community_id=?1 AND pubkey='alice' AND policy_version='v1'").bind(community.as_uuid().to_string()).fetch_one(&pool).await.unwrap(), 1); + + let unlimited = [8_u8; 32]; + sqlx::query("INSERT INTO relay_invites (community_id,id,token_hash,max_uses,expires_at,created_by) VALUES (?1,?2,?3,NULL,?4,'owner')") + .bind(community.as_uuid().to_string()).bind(Uuid::new_v4().to_string()).bind(unlimited.as_slice()).bind(now + 3600).execute(&pool).await.unwrap(); + assert_eq!( + claim_relay_invite(&pool, community, &unlimited, "carol", None) + .await + .unwrap(), + crate::relay_invite::ClaimOutcome::Joined { + use_count: 1, + uses_remaining: None + } + ); + assert_eq!( + claim_relay_invite(&pool, community, &unlimited, "dave", None) + .await + .unwrap(), + crate::relay_invite::ClaimOutcome::Joined { + use_count: 2, + uses_remaining: None + } + ); + + let expired = [9_u8; 32]; + sqlx::query("INSERT INTO relay_invites (community_id,id,token_hash,max_uses,expires_at,created_by) VALUES (?1,?2,?3,1,?4,'owner')") + .bind(community.as_uuid().to_string()).bind(Uuid::new_v4().to_string()).bind(expired.as_slice()).bind(now - 10).execute(&pool).await.unwrap(); + assert_eq!( + claim_relay_invite(&pool, community, &expired, "erin", None) + .await + .unwrap(), + crate::relay_invite::ClaimOutcome::Expired + ); + assert_eq!( + reap_expired_relay_invites(&pool, chrono::Utc::now()) + .await + .unwrap(), + 1 + ); + } + #[tokio::test] async fn core_slice_survives_temporary_file_reopen() { let path = std::env::temp_dir().join(format!("buzz-db-{}.sqlite", Uuid::new_v4()));