upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/grasp-audit/src
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-11-05 12:50:03 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-11-05 12:50:03 +0000
commit64a86de9fc5ded51a1b5405223fc5dce16839fef (patch)
tree9c981e337d3c3908776aa41c1eaff6c3e44cba14 /grasp-audit/src
parent94bf5c39af0d8d0a9a15db240d5d46383ec22160 (diff)
Refactor: abstract announcement event creation into AuditClient helper
- Add create_repo_announcement() method to AuditClient - Remove duplicate code from nip01_smoke.rs - Update grasp01_nostr_relay.rs to use centralized helper - All tests passing (GRASP-01: 4/18, NIP-01: 6/6)
Diffstat (limited to 'grasp-audit/src')
-rw-r--r--grasp-audit/src/client.rs43
-rw-r--r--grasp-audit/src/specs/grasp01_nostr_relay.rs31
-rw-r--r--grasp-audit/src/specs/nip01_smoke.rs43
3 files changed, 59 insertions, 58 deletions
diff --git a/grasp-audit/src/client.rs b/grasp-audit/src/client.rs
index b80b59f..7706ee3 100644
--- a/grasp-audit/src/client.rs
+++ b/grasp-audit/src/client.rs
@@ -158,6 +158,49 @@ impl AuditClient {
158 pub fn keys(&self) -> &Keys { 158 pub fn keys(&self) -> &Keys {
159 &self.keys 159 &self.keys
160 } 160 }
161
162 /// Create a NIP-34 repository announcement event
163 ///
164 /// This helper creates a properly formatted NIP-34 announcement that will be
165 /// accepted by GRASP relays (which require events to list the relay in clone/relays tags).
166 ///
167 /// # Arguments
168 /// * `test_name` - Name of the test (used to create unique repo identifier)
169 ///
170 /// # Returns
171 /// A built and signed Event ready to be sent to the relay
172 pub async fn create_repo_announcement(&self, test_name: &str) -> Result<Event> {
173 // Get relay URL from client
174 let relay_url = self.client.relays().await
175 .keys()
176 .next()
177 .ok_or_else(|| anyhow!("No relay connected"))?
178 .to_string();
179
180 // Convert WebSocket URL to HTTP URL for clone tag
181 let http_url = relay_url
182 .replace("ws://", "http://")
183 .replace("wss://", "https://");
184
185 // Create unique repository identifier using UUID for consistency
186 let repo_id = format!("{}-{}", test_name, uuid::Uuid::new_v4());
187
188 // Get npub for clone URL
189 let npub = self.public_key().to_bech32()
190 .map_err(|e| anyhow!("Failed to convert public key to bech32 npub format: {}", e))?;
191
192 // Build kind 30617 repository announcement
193 let event = self.event_builder(Kind::GitRepoAnnouncement, format!("Test repository for {}", test_name))
194 .tag(Tag::identifier(&repo_id))
195 .tag(Tag::custom(TagKind::custom("name"), vec![format!("{} Test Repository", test_name)]))
196 .tag(Tag::custom(TagKind::custom("description"), vec![format!("Repository for {} testing", test_name)]))
197 .tag(Tag::custom(TagKind::custom("clone"), vec![format!("{}/{}/{}.git", http_url, npub, repo_id)]))
198 .tag(Tag::custom(TagKind::custom("relays"), vec![relay_url.clone()]))
199 .build(self.keys())
200 .map_err(|e| anyhow!("Failed to build repository announcement event: {}", e))?;
201
202 Ok(event)
203 }
161} 204}
162 205
163#[cfg(test)] 206#[cfg(test)]
diff --git a/grasp-audit/src/specs/grasp01_nostr_relay.rs b/grasp-audit/src/specs/grasp01_nostr_relay.rs
index 5a93672..837434b 100644
--- a/grasp-audit/src/specs/grasp01_nostr_relay.rs
+++ b/grasp-audit/src/specs/grasp01_nostr_relay.rs
@@ -64,35 +64,28 @@ impl Grasp01NostrRelayTests {
64 "Accept valid repository announcements with service in clone and relays tags", 64 "Accept valid repository announcements with service in clone and relays tags",
65 ) 65 )
66 .run(|| async { 66 .run(|| async {
67 // Get relay URL from client 67 // Create a NIP-34 repository announcement event
68 let event = client.create_repo_announcement("accept_valid_repo_announcement").await
69 .map_err(|e| format!("Failed to create repository announcement: {}", e))?;
70
71 // Get relay URL for validation
68 let relay_url = client.client().relays().await 72 let relay_url = client.client().relays().await
69 .keys() 73 .keys()
70 .next() 74 .next()
71 .ok_or("No relay connected")? 75 .ok_or("No relay connected")?
72 .to_string(); 76 .to_string();
73 77
74 // Convert WebSocket URL to HTTP URL for clone tag 78 // Convert WebSocket URL to HTTP URL for validation
75 let http_url = relay_url 79 let http_url = relay_url
76 .replace("ws://", "http://") 80 .replace("ws://", "http://")
77 .replace("wss://", "https://"); 81 .replace("wss://", "https://");
78 82
79 // Create unique repository identifier 83 // Extract repo_id from the event's d tag
80 let timestamp = Timestamp::now().as_u64(); 84 let repo_id = event.tags.iter()
81 let repo_id = format!("test-repo-{}", timestamp); 85 .find(|t| t.kind() == TagKind::d())
82 86 .and_then(|t| t.content())
83 // Get npub for clone URL 87 .ok_or("Missing d tag in announcement")?
84 let npub = client.public_key().to_bech32() 88 .to_string();
85 .map_err(|e| format!("Failed to convert public key to bech32 npub format: {}", e))?;
86
87 // Build kind 30617 repository announcement
88 let event = client.event_builder(Kind::GitRepoAnnouncement, "")
89 .tag(Tag::identifier(&repo_id))
90 .tag(Tag::custom(TagKind::Custom("name".into()), vec!["GRASP-01 Test Repository"]))
91 .tag(Tag::custom(TagKind::Custom("description".into()), vec!["Test repository for GRASP-01 compliance testing"]))
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()]))
94 .build(client.keys())
95 .map_err(|e| format!("Failed to build repository announcement event (kind 30617): {}", e))?;
96 89
97 // Send the event 90 // Send the event
98 let event_id = client.send_event(event.clone()).await 91 let event_id = client.send_event(event.clone()).await
diff --git a/grasp-audit/src/specs/nip01_smoke.rs b/grasp-audit/src/specs/nip01_smoke.rs
index cb256c5..9ed0f56 100644
--- a/grasp-audit/src/specs/nip01_smoke.rs
+++ b/grasp-audit/src/specs/nip01_smoke.rs
@@ -10,43 +10,6 @@ use nostr_sdk::prelude::*;
10pub struct Nip01SmokeTests; 10pub struct Nip01SmokeTests;
11 11
12impl Nip01SmokeTests { 12impl Nip01SmokeTests {
13 /// Create a NIP-34 repository announcement event
14 ///
15 /// This helper creates a properly formatted NIP-34 announcement that will be
16 /// accepted by GRASP relays (which require events to list the relay in clone/relays tags).
17 async fn create_announcement_event(client: &AuditClient, test_name: &str) -> Result<Event, String> {
18 // Get relay URL from client
19 let relay_url = client.client().relays().await
20 .keys()
21 .next()
22 .ok_or("No relay URL found")?
23 .to_string();
24
25 // Convert ws:// to http:// for clone URL
26 let http_url = relay_url
27 .replace("ws://", "http://")
28 .replace("wss://", "https://");
29
30 // Create unique repository identifier
31 let repo_id = format!("{}-{}", test_name, uuid::Uuid::new_v4());
32 let npub = client.public_key().to_bech32()
33 .map_err(|e| format!("Failed to encode npub: {}", e))?;
34
35 // Create NIP-34 repository announcement (kind 30617)
36 // This event lists the GRASP server, so it should be accepted
37 let event = client
38 .event_builder(Kind::Custom(30617), format!("NIP-01 smoke test repository: {}", test_name))
39 .tag(Tag::identifier(&repo_id)) // d tag
40 .tag(Tag::custom(TagKind::Custom("name".into()), vec![format!("{} Test Repo", test_name)]))
41 .tag(Tag::custom(TagKind::Custom("description".into()), vec![format!("Repository for {} smoke testing", test_name)]))
42 .tag(Tag::custom(TagKind::Custom("clone".into()), vec![format!("{}/{}/{}.git", http_url, npub, repo_id)]))
43 .tag(Tag::custom(TagKind::Custom("relays".into()), vec![relay_url.clone()]))
44 .build(client.keys())
45 .map_err(|e| format!("Failed to build event: {}", e))?;
46
47 Ok(event)
48 }
49
50 /// Run all NIP-01 smoke tests 13 /// Run all NIP-01 smoke tests
51 pub async fn run_all(client: &AuditClient) -> AuditResult { 14 pub async fn run_all(client: &AuditClient) -> AuditResult {
52 let mut results = AuditResult::new("NIP-01 Smoke Tests"); 15 let mut results = AuditResult::new("NIP-01 Smoke Tests");
@@ -97,7 +60,8 @@ impl Nip01SmokeTests {
97 ) 60 )
98 .run(|| async { 61 .run(|| async {
99 // Create a NIP-34 announcement event 62 // Create a NIP-34 announcement event
100 let event = Self::create_announcement_event(client, "send_receive_event").await?; 63 let event = client.create_repo_announcement("send_receive_event").await
64 .map_err(|e| format!("Failed to create announcement: {}", e))?;
101 65
102 // Send event 66 // Send event
103 let event_id = client 67 let event_id = client
@@ -161,7 +125,8 @@ impl Nip01SmokeTests {
161 ) 125 )
162 .run(|| async { 126 .run(|| async {
163 // Create a NIP-34 announcement event (accepted by GRASP relays) 127 // Create a NIP-34 announcement event (accepted by GRASP relays)
164 let event = Self::create_announcement_event(client, "create_subscription").await?; 128 let event = client.create_repo_announcement("create_subscription").await
129 .map_err(|e| format!("Failed to create announcement: {}", e))?;
165 130
166 let event_id = client 131 let event_id = client
167 .send_event(event.clone()) 132 .send_event(event.clone())