diff options
Diffstat (limited to 'grasp-audit/src/specs')
| -rw-r--r-- | grasp-audit/src/specs/grasp01_nostr_relay.rs | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/grasp-audit/src/specs/grasp01_nostr_relay.rs b/grasp-audit/src/specs/grasp01_nostr_relay.rs index 7c4ef1e..5a93672 100644 --- a/grasp-audit/src/specs/grasp01_nostr_relay.rs +++ b/grasp-audit/src/specs/grasp01_nostr_relay.rs | |||
| @@ -82,7 +82,7 @@ impl Grasp01NostrRelayTests { | |||
| 82 | 82 | ||
| 83 | // Get npub for clone URL | 83 | // Get npub for clone URL |
| 84 | let npub = client.public_key().to_bech32() | 84 | let npub = client.public_key().to_bech32() |
| 85 | .map_err(|e| format!("Failed to convert pubkey to npub: {}", e))?; | 85 | .map_err(|e| format!("Failed to convert public key to bech32 npub format: {}", e))?; |
| 86 | 86 | ||
| 87 | // Build kind 30617 repository announcement | 87 | // Build kind 30617 repository announcement |
| 88 | let event = client.event_builder(Kind::GitRepoAnnouncement, "") | 88 | let event = client.event_builder(Kind::GitRepoAnnouncement, "") |
| @@ -92,11 +92,11 @@ impl Grasp01NostrRelayTests { | |||
| 92 | .tag(Tag::custom(TagKind::Custom("clone".into()), vec![format!("{}/{}/{}.git", http_url, npub, repo_id)])) | 92 | .tag(Tag::custom(TagKind::Custom("clone".into()), vec![format!("{}/{}/{}.git", http_url, npub, repo_id)])) |
| 93 | .tag(Tag::custom(TagKind::Custom("relays".into()), vec![relay_url.clone()])) | 93 | .tag(Tag::custom(TagKind::Custom("relays".into()), vec![relay_url.clone()])) |
| 94 | .build(client.keys()) | 94 | .build(client.keys()) |
| 95 | .map_err(|e| format!("Failed to build event: {}", e))?; | 95 | .map_err(|e| format!("Failed to build repository announcement event (kind 30617): {}", e))?; |
| 96 | 96 | ||
| 97 | // Send the event | 97 | // Send the event |
| 98 | let event_id = client.send_event(event.clone()).await | 98 | let event_id = client.send_event(event.clone()).await |
| 99 | .map_err(|e| format!("Failed to send event: {}", e))?; | 99 | .map_err(|e| format!("Failed to send repository announcement to relay: {}", e))?; |
| 100 | 100 | ||
| 101 | // Query back to verify it was accepted and stored | 101 | // Query back to verify it was accepted and stored |
| 102 | let filter = Filter::new() | 102 | let filter = Filter::new() |
| @@ -105,17 +105,23 @@ impl Grasp01NostrRelayTests { | |||
| 105 | .identifier(&repo_id); | 105 | .identifier(&repo_id); |
| 106 | 106 | ||
| 107 | let events = client.query(filter).await | 107 | let events = client.query(filter).await |
| 108 | .map_err(|e| format!("Failed to query events: {}", e))?; | 108 | .map_err(|e| format!("Failed to query events from relay: {}", e))?; |
| 109 | 109 | ||
| 110 | // Verify we got the event back | 110 | // Verify we got the event back |
| 111 | if events.is_empty() { | 111 | if events.is_empty() { |
| 112 | return Err("Event was not stored in relay (possibly rejected)".to_string()); | 112 | return Err(format!( |
| 113 | "Event was not stored in relay (possibly rejected). Event ID: {}, Repo ID: {}", | ||
| 114 | event_id, repo_id | ||
| 115 | )); | ||
| 113 | } | 116 | } |
| 114 | 117 | ||
| 115 | // Verify it's the same event | 118 | // Verify it's the same event |
| 116 | let stored_event = events.iter() | 119 | let stored_event = events.iter() |
| 117 | .find(|e| e.id == event_id) | 120 | .find(|e| e.id == event_id) |
| 118 | .ok_or("Stored event ID doesn't match sent event")?; | 121 | .ok_or(format!( |
| 122 | "Stored event ID doesn't match sent event. Expected: {}, Got {} events", | ||
| 123 | event_id, events.len() | ||
| 124 | ))?; | ||
| 119 | 125 | ||
| 120 | // Verify key tags are present | 126 | // Verify key tags are present |
| 121 | let has_clone_tag = stored_event.tags.iter() | 127 | let has_clone_tag = stored_event.tags.iter() |
| @@ -158,7 +164,7 @@ impl Grasp01NostrRelayTests { | |||
| 158 | let relay_url = client.client().relays().await | 164 | let relay_url = client.client().relays().await |
| 159 | .keys() | 165 | .keys() |
| 160 | .next() | 166 | .next() |
| 161 | .ok_or("No relay connected")? | 167 | .ok_or("No relay connected - client has no active relay connections")? |
| 162 | .to_string(); | 168 | .to_string(); |
| 163 | 169 | ||
| 164 | // Create unique repository identifier | 170 | // Create unique repository identifier |
| @@ -186,11 +192,15 @@ impl Grasp01NostrRelayTests { | |||
| 186 | .identifier(&repo_id); | 192 | .identifier(&repo_id); |
| 187 | 193 | ||
| 188 | let events = client.query(filter).await | 194 | let events = client.query(filter).await |
| 189 | .map_err(|e| format!("Failed to query events: {}", e))?; | 195 | .map_err(|e| format!("Failed to query events from relay: {}", e))?; |
| 190 | 196 | ||
| 191 | // Verify event was rejected (not stored) | 197 | // Verify event was rejected (not stored) |
| 192 | if events.iter().any(|e| e.id == event_id) { | 198 | if events.iter().any(|e| e.id == event_id) { |
| 193 | return Err("Relay accepted announcement without service in clone tag - should reject".to_string()); | 199 | return Err(format!( |
| 200 | "Relay incorrectly accepted announcement without service in clone tag. \ | ||
| 201 | Event ID: {}, Clone URL: https://github.com/user/repo.git (should require {})", | ||
| 202 | event_id, relay_url | ||
| 203 | )); | ||
| 194 | } | 204 | } |
| 195 | 205 | ||
| 196 | Ok(()) | 206 | Ok(()) |
| @@ -650,16 +660,21 @@ mod tests { | |||
| 650 | use super::*; | 660 | use super::*; |
| 651 | use crate::AuditConfig; | 661 | use crate::AuditConfig; |
| 652 | 662 | ||
| 653 | #[tokio::test] | 663 | #[tokio::test] |
| 654 | #[ignore] // Requires running relay | 664 | #[ignore] // Requires running relay |
| 655 | async fn test_grasp01_nostr_relay_against_relay() { | 665 | async fn test_grasp01_nostr_relay_against_relay() { |
| 656 | // Read relay URL from environment variable - must be supplied | 666 | // Read relay URL from environment variable - must be supplied |
| 657 | let relay_url = std::env::var("RELAY_URL")?; | 667 | let relay_url = std::env::var("RELAY_URL") |
| 658 | 668 | .expect("RELAY_URL environment variable must be set. Example: RELAY_URL=ws://localhost:18081"); | |
| 659 | let config = AuditConfig::ci(); | 669 | |
| 660 | let client = AuditClient::new(&relay_url, config) | 670 | let config = AuditConfig::ci(); |
| 661 | .await | 671 | let client = AuditClient::new(&relay_url, config) |
| 662 | .expect("Failed to connect to relay"); | 672 | .await |
| 673 | .expect(&format!( | ||
| 674 | "Failed to connect to relay at {}. Ensure relay is running and accessible. \ | ||
| 675 | Try: docker run --rm -p 18081:8081 ghcr.io/danconwaydev/ngit-relay:latest", | ||
| 676 | relay_url | ||
| 677 | )); | ||
| 663 | 678 | ||
| 664 | let results = Grasp01NostrRelayTests::run_all(&client).await; | 679 | let results = Grasp01NostrRelayTests::run_all(&client).await; |
| 665 | results.print_report(); | 680 | results.print_report(); |