test(relay): cover current community entry points

Keep invitation and webhook-owner gaps explicit until their implementations are integrated.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Brad Seiler <seiler@squareup.com>
This commit is contained in:
Brad Seiler
2026-10-09 19:15:14 -04:00
parent 1e23dfc864
commit 85c14ae8ea
3 changed files with 20 additions and 6 deletions

View File

@@ -28,6 +28,8 @@ const BANNED_MESSAGE: &str = "blocked: you are banned from this community";
const COMMUNITY_BAN_MATRIX_CASES: &[&str] = &[
"events",
"buzz_sidebar",
"buzz_read_state",
"moderation_command",
"query",
"count",
@@ -268,7 +270,7 @@ fn request_body(case: &str, actor: &Principal) -> Vec<u8> {
"limit": 1
}]))
.expect("serialize Nostr filter"),
"gif_search" | "gif_share" | "invite_mint" => b"{".to_vec(),
"gif_search" | "gif_share" | "invite_mint" | "buzz_read_state" => b"{".to_vec(),
"media_upload" => b"not an image file".to_vec(),
"git_upload_pack" | "git_receive_pack" => Vec::new(),
"git_default_post" => serde_json::to_vec(&serde_json::json!({
@@ -406,6 +408,12 @@ fn assert_ban_denial(
route.method,
route.path
);
} else if route.id.starts_with("buzz_") {
assert_eq!(
serde_json::from_str::<serde_json::Value>(body).expect("accessory denial JSON")
["error"]["code"],
"forbidden"
);
} else if route.method == "HEAD" {
assert!(
body.is_empty(),

View File

@@ -31,7 +31,7 @@ nip_fi_disconnect relay POST /api/nip-fi/disconnect internal_nip_fi not_applicab
moderation_reports relay GET /moderation/reports community_nip98 community enforce matrix:moderation_reports+moderation_owner_ban admin
moderation_audit relay GET /moderation/audit community_nip98 community enforce matrix:moderation_audit+moderation_owner_ban admin
moderation_restricted relay GET /moderation/restricted community_nip98 community enforce matrix:moderation_restricted+moderation_owner_ban admin
workflow_webhook relay POST /hooks/{id} workflow_webhook_secret not_applicable not_applicable:webhook_secret_auth classified -
workflow_webhook relay POST /hooks/{id} workflow_webhook_secret not_applicable enforce pending:BUZZ-272 BUZZ-272
mesh_demo_echo relay POST /_mesh/demo/echo testbed_internal not_applicable not_applicable:testbed_only classified -
huddle_audio relay GET /huddle/{channel_id}/audio community_nip42 community enforce pg:audio_join_rejects_community_banned_member+audio_join_rejects_banned_admin+audio_join_rejects_banned_owner_agent -
media_upload relay PUT /upload community_blossom community enforce matrix:media_upload member
@@ -67,3 +67,9 @@ health_liveness health GET /_liveness health_probe not_applicable not_applicable
health_readiness health GET /_readiness health_probe not_applicable not_applicable:health_probe classified -
health_status health GET /_status health_probe not_applicable not_applicable:health_probe classified -
health_mesh health GET /_mesh health_probe not_applicable not_applicable:health_probe classified -
admin_communities relay GET /api/admin/v1/communities operator_control not_applicable not_applicable:relay_admin_control classified -
admin_event relay GET /api/admin/v1/events/{id} operator_control not_applicable not_applicable:relay_admin_control classified -
admin_member_search relay GET /api/admin/v1/members/search operator_control not_applicable not_applicable:relay_admin_control classified -
admin_member relay GET /api/admin/v1/members/{pubkey} operator_control not_applicable not_applicable:relay_admin_control classified -
buzz_sidebar relay GET /buzz/v1/me/sidebar community_nip98 community enforce matrix:buzz_sidebar member
buzz_read_state relay POST /buzz/v1/me/read-state community_nip98 community enforce matrix:buzz_read_state member
1 id listener method path auth_plane membership restriction exercise control
31 moderation_reports relay GET /moderation/reports community_nip98 community enforce matrix:moderation_reports+moderation_owner_ban admin
32 moderation_audit relay GET /moderation/audit community_nip98 community enforce matrix:moderation_audit+moderation_owner_ban admin
33 moderation_restricted relay GET /moderation/restricted community_nip98 community enforce matrix:moderation_restricted+moderation_owner_ban admin
34 workflow_webhook relay POST /hooks/{id} workflow_webhook_secret not_applicable not_applicable:webhook_secret_auth enforce classified pending:BUZZ-272 - BUZZ-272
35 mesh_demo_echo relay POST /_mesh/demo/echo testbed_internal not_applicable not_applicable:testbed_only classified -
36 huddle_audio relay GET /huddle/{channel_id}/audio community_nip42 community enforce pg:audio_join_rejects_community_banned_member+audio_join_rejects_banned_admin+audio_join_rejects_banned_owner_agent -
37 media_upload relay PUT /upload community_blossom community enforce matrix:media_upload member
67 health_readiness health GET /_readiness health_probe not_applicable not_applicable:health_probe classified -
68 health_status health GET /_status health_probe not_applicable not_applicable:health_probe classified -
69 health_mesh health GET /_mesh health_probe not_applicable not_applicable:health_probe classified -
70 admin_communities relay GET /api/admin/v1/communities operator_control not_applicable not_applicable:relay_admin_control classified -
71 admin_event relay GET /api/admin/v1/events/{id} operator_control not_applicable not_applicable:relay_admin_control classified -
72 admin_member_search relay GET /api/admin/v1/members/search operator_control not_applicable not_applicable:relay_admin_control classified -
73 admin_member relay GET /api/admin/v1/members/{pubkey} operator_control not_applicable not_applicable:relay_admin_control classified -
74 buzz_sidebar relay GET /buzz/v1/me/sidebar community_nip98 community enforce matrix:buzz_sidebar member
75 buzz_read_state relay POST /buzz/v1/me/read-state community_nip98 community enforce matrix:buzz_read_state member

View File

@@ -293,7 +293,7 @@ def builder_prefixes(builders) -> dict[str, str]:
_, _, path, source, mask, start, _, end = main
prefixes = {}
for first, second_mask, second_source in registered_calls(mask, source, start, end, "nest"):
prefix = string_value(first)
prefix = route_path(first, route_constants())
target_match = re.search(r"((?:[A-Za-z_]\w*::)*[A-Za-z_]\w*)\s*\(", second_mask)
if prefix is None or target_match is None:
continue
@@ -485,9 +485,9 @@ def check_route_inventory() -> tuple[int, int, int]:
details.append("inventory rows without registered routes: " + ", ".join(map(str, stale)))
raise ValueError("; ".join(details))
if len(pending) != 1 or pending[0] != ("invite_claim", "pending:BUZZ-268"):
if set(pending) != {("invite_claim", "pending:BUZZ-268"), ("workflow_webhook", "pending:BUZZ-272")}:
raise ValueError(
"the only pending route coverage must be invite_claim pending:BUZZ-268"
"pending coverage must explicitly track BUZZ-268 invitations and BUZZ-272 webhook owner bans"
)
claim = next((row for row in routes if row["id"] == "invite_claim"), None)
if claim is None or claim["membership"] != "exempt" or claim["restriction"] != "enforce":
@@ -547,7 +547,7 @@ def main() -> int:
print(
"community-ban route inventory passed: "
f"{route_count} registered routes classified, {case_count} HTTP behavior cases, "
f"{regression_count} supporting regressions indexed, {pending_count} BUZZ-268 invite case pending"
f"{regression_count} supporting regressions indexed, {pending_count} sibling implementation cases pending"
)
return 0