test(relay): harden NIP-37 coverage matrix — non-vacuous tests, Clippy clean

Fix all remaining quality gaps identified in the pre-Thufir review:

Clippy (FIX-11):
- Remove 17 needless borrows in e2e_nip37_draft.rs (auto-fixed)
- sort_by → sort_by_key in tie-break test (auto-fixed)
- while_let_loop → while let loop in removed-member fan-out test
- splitn(3, ':').next() → split(':').next() in ingest.rs NIP-09 guard

DB tests (CRITICAL-A-test, FIX-4, FIX-5):
- Add build_test_draft_at helper (explicit timestamp control)
- Add query_draft_head helper (reusable across tests)
- Expand draft_is_confined_to_its_community: full A/B lifecycle (insert →
  query → replace → tombstone) with scoped head assertions after each step;
  uses same d_tag in both communities to prove community_id is the real
  isolation boundary
- Add draft_channel_binding_is_immutable_across_sequential_calls: sequential
  rebind attempt on an already-bound address → DraftChannelMismatch; stored
  head still v1 after failed rebind
- Add post-race head query to concurrent_different_channel_drafts_one_wins_one_loses:
  assert exactly one live head bound to the winning channel after the race

E2E tests (CRITICAL-B-test, FIX-6, FIX-7, FIX-8, FIX-9, FIX-10):
- Add test_nip09_a_tag_deletion_of_draft_is_rejected: kind:5 a-tag targeting
  31234:<pubkey>:<d> must be rejected; draft must still be live head after
- FIX-7: Expand workflow tripwire to evaluate the actual dispatch predicate
  (is_workflow_execution_kind && is_command_kind && AUTHOR_ONLY_KINDS) for
  kind:31234 (→ false) and kind:9 (→ true, positive control)
- FIX-8: DM test — replace silent return with panic! on missing channel_id;
  use strictly increasing timestamps (base-2, base-1, base) to guarantee
  deterministic ordering across v1/v2/tombstone
- FIX-6: test_draft_not_returned_in_kindless_channel_query — rewrite to use
  attacker (not owner) as requester; the author-only gate strips drafts from
  non-author queries, not from the author's own channel queries
- FIX-9: Removed-member live fan-out — use author(owner) subscription so the
  probe event (owner draft) actually matches the filter and exercises the gate
- FIX-10: Rename test_draft_tenant_confinement_channel_from_different_community
  → inline note + pointer to the existing test_draft_rejected_nonexistent_channel_h_tag
  (the old name was misleading; true cross-tenant confinement is the DB test)

CI (FIX-CI):
- Wire buzz-db NIP-37 draft Postgres tests to backend-integration job

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7
2026-07-14 00:21:25 -04:00
committed by Will Pfleger
co-authored by Will Pfleger
parent e3a0e257bc
commit 6fcb8a723d
7 changed files with 489 additions and 189 deletions
+9
View File
@@ -620,6 +620,15 @@ jobs:
run: cargo test --profile ci -p buzz-test-client --test e2e_nip37_draft -- --ignored
env:
RELAY_URL: ws://localhost:3000
- name: NIP-37 draft wrap DB tests
# DB-layer tests for NIP-37 draft wraps: tenant confinement (A/B
# independent heads across communities), immutable channel-binding
# (sequential rebind → DraftChannelMismatch), and race-guard
# (concurrent writes → exactly one winner + one DraftChannelMismatch).
# These run directly against Postgres without a relay process.
run: cargo test --profile ci -p buzz-db -- draft --ignored
env:
DATABASE_URL: postgres://buzz:buzz_dev@localhost:5432/buzz
- name: Upload relay log
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7