diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-11-05 08:33:38 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-11-05 08:33:38 +0000 |
| commit | fa9753e020afaefea96d106259770b6c836d1111 (patch) | |
| tree | 642c653d9374740883749b238b51daf901c7bf7b /grasp-audit/src/specs | |
| parent | c2183f156a767c1443c7ae62954fe8192e349ceb (diff) | |
feat(grasp-audit): implement test_reject_repo_announcement_missing_clone_tag
- Tests that relay rejects repo announcements without service in clone tag
- Validates GRASP-01 line 5 requirement
- Tested against ngit-relay on port 18081
- Test passes (4/18 GRASP-01 Nostr relay tests now passing)
Diffstat (limited to 'grasp-audit/src/specs')
| -rw-r--r-- | grasp-audit/src/specs/grasp01_nostr_relay.rs | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/grasp-audit/src/specs/grasp01_nostr_relay.rs b/grasp-audit/src/specs/grasp01_nostr_relay.rs index a81132d..a18927c 100644 --- a/grasp-audit/src/specs/grasp01_nostr_relay.rs +++ b/grasp-audit/src/specs/grasp01_nostr_relay.rs | |||
| @@ -154,17 +154,46 @@ impl Grasp01NostrRelayTests { | |||
| 154 | "Reject repository announcements without service in clone tag", | 154 | "Reject repository announcements without service in clone tag", |
| 155 | ) | 155 | ) |
| 156 | .run(|| async { | 156 | .run(|| async { |
| 157 | // TODO: Implementation | 157 | // Get relay URL from client |
| 158 | // 1. Create kind 30617 event with: | 158 | let relay_url = client.client().relays().await |
| 159 | // - d tag: "test-repo-no-clone" | 159 | .keys() |
| 160 | // - clone tag: "https://github.com/user/repo.git" (NOT this service) | 160 | .next() |
| 161 | // - relays tag: "{service_url}" (correct) | 161 | .ok_or("No relay connected")? |
| 162 | // 2. Send event to relay | 162 | .to_string(); |
| 163 | // 3. Verify rejection (error in OK response or event not stored) | ||
| 164 | // 4. Query to confirm event is NOT in relay | ||
| 165 | // 5. Document expected error message if available | ||
| 166 | 163 | ||
| 167 | Err("Not implemented yet".to_string()) | 164 | // Create unique repository identifier |
| 165 | let timestamp = Timestamp::now().as_u64(); | ||
| 166 | let repo_id = format!("test-repo-no-clone-{}", timestamp); | ||
| 167 | |||
| 168 | // Create repo announcement WITHOUT service in clone tag | ||
| 169 | let event = client.event_builder(Kind::GitRepoAnnouncement, "") | ||
| 170 | .tag(Tag::identifier(&repo_id)) | ||
| 171 | .tag(Tag::custom(TagKind::Custom("name".into()), vec!["Test Repo No Clone"])) | ||
| 172 | .tag(Tag::custom(TagKind::Custom("clone".into()), vec!["https://github.com/user/repo.git"])) // NOT this service | ||
| 173 | .tag(Tag::custom(TagKind::Custom("relays".into()), vec![relay_url.clone()])) // Correct relay | ||
| 174 | .build(client.keys()) | ||
| 175 | .map_err(|e| format!("Failed to build event: {}", e))?; | ||
| 176 | |||
| 177 | let event_id = event.id; | ||
| 178 | |||
| 179 | // Send event - expect rejection | ||
| 180 | let send_result = client.send_event(event.clone()).await; | ||
| 181 | |||
| 182 | // Query to verify event is NOT stored | ||
| 183 | let filter = Filter::new() | ||
| 184 | .kind(Kind::GitRepoAnnouncement) | ||
| 185 | .author(client.public_key()) | ||
| 186 | .identifier(&repo_id); | ||
| 187 | |||
| 188 | let events = client.query(filter).await | ||
| 189 | .map_err(|e| format!("Failed to query events: {}", e))?; | ||
| 190 | |||
| 191 | // Verify event was rejected (not stored) | ||
| 192 | if events.iter().any(|e| e.id == event_id) { | ||
| 193 | return Err("Relay accepted announcement without service in clone tag - should reject".to_string()); | ||
| 194 | } | ||
| 195 | |||
| 196 | Ok(()) | ||
| 168 | }) | 197 | }) |
| 169 | .await | 198 | .await |
| 170 | } | 199 | } |