diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-12 12:36:23 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-12 12:36:23 +0000 |
| commit | 3fd6ce4149d567c67009b0332ca76c0cd6f51055 (patch) | |
| tree | 2316c9a07fafcf419bea4369823ff9741c755080 /grasp-audit/src/specs/grasp01/git_clone.rs | |
| parent | 869fd91e5c652c48a32d284eedc989a79c7afaea (diff) | |
refactor(grasp-audit): introduce SpecRef enum for type-safe spec references
Replace string-based spec references with typed SpecRef enum for
compile-time validation and better IDE support. TestResult::new() now
accepts SpecRef enum plus a requirement description string for
test-specific context.
Diffstat (limited to 'grasp-audit/src/specs/grasp01/git_clone.rs')
| -rw-r--r-- | grasp-audit/src/specs/grasp01/git_clone.rs | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/grasp-audit/src/specs/grasp01/git_clone.rs b/grasp-audit/src/specs/grasp01/git_clone.rs index e162558..fda472b 100644 --- a/grasp-audit/src/specs/grasp01/git_clone.rs +++ b/grasp-audit/src/specs/grasp01/git_clone.rs | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | //! cd grasp-audit && nix develop -c bash test-ngit-relay.sh --mode test | 15 | //! cd grasp-audit && nix develop -c bash test-ngit-relay.sh --mode test |
| 16 | //! ``` | 16 | //! ``` |
| 17 | 17 | ||
| 18 | use crate::specs::grasp01::SpecRef; | ||
| 18 | use crate::{AuditClient, FixtureKind, TestContext, TestResult}; | 19 | use crate::{AuditClient, FixtureKind, TestContext, TestResult}; |
| 19 | use nostr_sdk::prelude::*; | 20 | use nostr_sdk::prelude::*; |
| 20 | use std::fs; | 21 | use std::fs; |
| @@ -53,7 +54,7 @@ impl GitCloneTests { | |||
| 53 | Err(e) => { | 54 | Err(e) => { |
| 54 | return TestResult::new( | 55 | return TestResult::new( |
| 55 | test_name, | 56 | test_name, |
| 56 | "GRASP-01:git-http:34", | 57 | SpecRef::GitServeRepository, |
| 57 | "Repository must be cloneable via Git HTTP backend", | 58 | "Repository must be cloneable via Git HTTP backend", |
| 58 | ) | 59 | ) |
| 59 | .fail(format!("Failed to create repo fixture: {}", e)) | 60 | .fail(format!("Failed to create repo fixture: {}", e)) |
| @@ -74,7 +75,7 @@ impl GitCloneTests { | |||
| 74 | None => { | 75 | None => { |
| 75 | return TestResult::new( | 76 | return TestResult::new( |
| 76 | test_name, | 77 | test_name, |
| 77 | "GRASP-01", | 78 | SpecRef::GitServeRepository, |
| 78 | "Repository must be cloneable via Git HTTP backend", | 79 | "Repository must be cloneable via Git HTTP backend", |
| 79 | ) | 80 | ) |
| 80 | .fail("Repository announcement missing d tag") | 81 | .fail("Repository announcement missing d tag") |
| @@ -86,7 +87,7 @@ impl GitCloneTests { | |||
| 86 | Err(e) => { | 87 | Err(e) => { |
| 87 | return TestResult::new( | 88 | return TestResult::new( |
| 88 | test_name, | 89 | test_name, |
| 89 | "GRASP-01:git-http:34", | 90 | SpecRef::GitServeRepository, |
| 90 | "Repository must be cloneable via Git HTTP backend", | 91 | "Repository must be cloneable via Git HTTP backend", |
| 91 | ) | 92 | ) |
| 92 | .fail(format!("Failed to convert pubkey to npub: {}", e)) | 93 | .fail(format!("Failed to convert pubkey to npub: {}", e)) |
| @@ -121,7 +122,7 @@ impl GitCloneTests { | |||
| 121 | cleanup(); | 122 | cleanup(); |
| 122 | return TestResult::new( | 123 | return TestResult::new( |
| 123 | test_name, | 124 | test_name, |
| 124 | "GRASP-01:git-http:34", | 125 | SpecRef::GitServeRepository, |
| 125 | "Repository must be cloneable via Git HTTP backend", | 126 | "Repository must be cloneable via Git HTTP backend", |
| 126 | ) | 127 | ) |
| 127 | .fail(format!("Failed to execute git clone: {}", e)); | 128 | .fail(format!("Failed to execute git clone: {}", e)); |
| @@ -133,7 +134,7 @@ impl GitCloneTests { | |||
| 133 | let stderr = String::from_utf8_lossy(&output.stderr); | 134 | let stderr = String::from_utf8_lossy(&output.stderr); |
| 134 | return TestResult::new( | 135 | return TestResult::new( |
| 135 | test_name, | 136 | test_name, |
| 136 | "GRASP-01:git-http:34", | 137 | SpecRef::GitServeRepository, |
| 137 | "Repository must be cloneable via Git HTTP backend", | 138 | "Repository must be cloneable via Git HTTP backend", |
| 138 | ) | 139 | ) |
| 139 | .fail(format!("Git clone failed: {}", stderr)); | 140 | .fail(format!("Git clone failed: {}", stderr)); |
| @@ -144,7 +145,7 @@ impl GitCloneTests { | |||
| 144 | cleanup(); | 145 | cleanup(); |
| 145 | return TestResult::new( | 146 | return TestResult::new( |
| 146 | test_name, | 147 | test_name, |
| 147 | "GRASP-01:git-http:34", | 148 | SpecRef::GitServeRepository, |
| 148 | "Repository must be cloneable via Git HTTP backend", | 149 | "Repository must be cloneable via Git HTTP backend", |
| 149 | ) | 150 | ) |
| 150 | .fail("Cloned repository missing .git directory"); | 151 | .fail("Cloned repository missing .git directory"); |
| @@ -153,7 +154,7 @@ impl GitCloneTests { | |||
| 153 | cleanup(); | 154 | cleanup(); |
| 154 | TestResult::new( | 155 | TestResult::new( |
| 155 | test_name, | 156 | test_name, |
| 156 | "GRASP-01:git-http:34", | 157 | SpecRef::GitServeRepository, |
| 157 | "Repository must be cloneable via Git HTTP backend", | 158 | "Repository must be cloneable via Git HTTP backend", |
| 158 | ) | 159 | ) |
| 159 | .pass() | 160 | .pass() |
| @@ -175,7 +176,7 @@ impl GitCloneTests { | |||
| 175 | Err(e) => { | 176 | Err(e) => { |
| 176 | return TestResult::new( | 177 | return TestResult::new( |
| 177 | test_name, | 178 | test_name, |
| 178 | "GRASP-01:git-http:34", | 179 | SpecRef::GitServeRepository, |
| 179 | "Clone URL must follow correct format", | 180 | "Clone URL must follow correct format", |
| 180 | ) | 181 | ) |
| 181 | .fail(format!("Failed to create repo fixture: {}", e)) | 182 | .fail(format!("Failed to create repo fixture: {}", e)) |
| @@ -203,7 +204,7 @@ impl GitCloneTests { | |||
| 203 | if !valid_url.contains(&npub) { | 204 | if !valid_url.contains(&npub) { |
| 204 | return TestResult::new( | 205 | return TestResult::new( |
| 205 | test_name, | 206 | test_name, |
| 206 | "GRASP-01:git-http:34", | 207 | SpecRef::GitServeRepository, |
| 207 | "Clone URL must follow correct format", | 208 | "Clone URL must follow correct format", |
| 208 | ) | 209 | ) |
| 209 | .fail("URL missing npub"); | 210 | .fail("URL missing npub"); |
| @@ -212,7 +213,7 @@ impl GitCloneTests { | |||
| 212 | if !valid_url.contains(&format!("{}.git", repo_id)) { | 213 | if !valid_url.contains(&format!("{}.git", repo_id)) { |
| 213 | return TestResult::new( | 214 | return TestResult::new( |
| 214 | test_name, | 215 | test_name, |
| 215 | "GRASP-01:git-http:34", | 216 | SpecRef::GitServeRepository, |
| 216 | "Clone URL must follow correct format", | 217 | "Clone URL must follow correct format", |
| 217 | ) | 218 | ) |
| 218 | .fail("URL missing repository identifier"); | 219 | .fail("URL missing repository identifier"); |
| @@ -241,7 +242,7 @@ impl GitCloneTests { | |||
| 241 | if output.status.success() { | 242 | if output.status.success() { |
| 242 | return TestResult::new( | 243 | return TestResult::new( |
| 243 | test_name, | 244 | test_name, |
| 244 | "GRASP-01:git-http:34", | 245 | SpecRef::GitServeRepository, |
| 245 | "Clone URL must follow correct format", | 246 | "Clone URL must follow correct format", |
| 246 | ) | 247 | ) |
| 247 | .fail("Invalid URL was accepted (should have been rejected)"); | 248 | .fail("Invalid URL was accepted (should have been rejected)"); |
| @@ -249,7 +250,7 @@ impl GitCloneTests { | |||
| 249 | 250 | ||
| 250 | TestResult::new( | 251 | TestResult::new( |
| 251 | test_name, | 252 | test_name, |
| 252 | "GRASP-01:git-http:34", | 253 | SpecRef::GitServeRepository, |
| 253 | "Clone URL must follow correct format", | 254 | "Clone URL must follow correct format", |
| 254 | ) | 255 | ) |
| 255 | .pass() | 256 | .pass() |
| @@ -278,7 +279,7 @@ impl GitCloneTests { | |||
| 278 | Err(e) => { | 279 | Err(e) => { |
| 279 | return TestResult::new( | 280 | return TestResult::new( |
| 280 | test_name, | 281 | test_name, |
| 281 | "GRASP-01:git-http:42", | 282 | SpecRef::GitIncludeAllowSha1InWant, |
| 282 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 283 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 283 | ) | 284 | ) |
| 284 | .fail(format!("Failed to create repo fixture: {}", e)) | 285 | .fail(format!("Failed to create repo fixture: {}", e)) |
| @@ -299,7 +300,7 @@ impl GitCloneTests { | |||
| 299 | None => { | 300 | None => { |
| 300 | return TestResult::new( | 301 | return TestResult::new( |
| 301 | test_name, | 302 | test_name, |
| 302 | "GRASP-01:git-http:42", | 303 | SpecRef::GitIncludeAllowSha1InWant, |
| 303 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 304 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 304 | ) | 305 | ) |
| 305 | .fail("Repository announcement missing d tag") | 306 | .fail("Repository announcement missing d tag") |
| @@ -311,7 +312,7 @@ impl GitCloneTests { | |||
| 311 | Err(e) => { | 312 | Err(e) => { |
| 312 | return TestResult::new( | 313 | return TestResult::new( |
| 313 | test_name, | 314 | test_name, |
| 314 | "GRASP-01:git-http:42", | 315 | SpecRef::GitIncludeAllowSha1InWant, |
| 315 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 316 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 316 | ) | 317 | ) |
| 317 | .fail(format!("Failed to convert pubkey to npub: {}", e)) | 318 | .fail(format!("Failed to convert pubkey to npub: {}", e)) |
| @@ -331,7 +332,7 @@ impl GitCloneTests { | |||
| 331 | Err(e) => { | 332 | Err(e) => { |
| 332 | return TestResult::new( | 333 | return TestResult::new( |
| 333 | test_name, | 334 | test_name, |
| 334 | "GRASP-01:git-http:42", | 335 | SpecRef::GitIncludeAllowSha1InWant, |
| 335 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 336 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 336 | ) | 337 | ) |
| 337 | .fail(format!("HTTP request failed: {}", e)) | 338 | .fail(format!("HTTP request failed: {}", e)) |
| @@ -341,7 +342,7 @@ impl GitCloneTests { | |||
| 341 | if !response.status().is_success() { | 342 | if !response.status().is_success() { |
| 342 | return TestResult::new( | 343 | return TestResult::new( |
| 343 | test_name, | 344 | test_name, |
| 344 | "GRASP-01:git-http:42", | 345 | SpecRef::GitIncludeAllowSha1InWant, |
| 345 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 346 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 346 | ) | 347 | ) |
| 347 | .fail(format!( | 348 | .fail(format!( |
| @@ -356,7 +357,7 @@ impl GitCloneTests { | |||
| 356 | Err(e) => { | 357 | Err(e) => { |
| 357 | return TestResult::new( | 358 | return TestResult::new( |
| 358 | test_name, | 359 | test_name, |
| 359 | "GRASP-01:git-http:42", | 360 | SpecRef::GitIncludeAllowSha1InWant, |
| 360 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 361 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 361 | ) | 362 | ) |
| 362 | .fail(format!("Failed to read response body: {}", e)) | 363 | .fail(format!("Failed to read response body: {}", e)) |
| @@ -370,7 +371,7 @@ impl GitCloneTests { | |||
| 370 | if !has_allow_reachable { | 371 | if !has_allow_reachable { |
| 371 | return TestResult::new( | 372 | return TestResult::new( |
| 372 | test_name, | 373 | test_name, |
| 373 | "GRASP-01:git-http:42", | 374 | SpecRef::GitIncludeAllowSha1InWant, |
| 374 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 375 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 375 | ) | 376 | ) |
| 376 | .fail("Missing capability: allow-reachable-sha1-in-want"); | 377 | .fail("Missing capability: allow-reachable-sha1-in-want"); |
| @@ -379,7 +380,7 @@ impl GitCloneTests { | |||
| 379 | if !has_allow_tip { | 380 | if !has_allow_tip { |
| 380 | return TestResult::new( | 381 | return TestResult::new( |
| 381 | test_name, | 382 | test_name, |
| 382 | "GRASP-01:git-http:42", | 383 | SpecRef::GitIncludeAllowSha1InWant, |
| 383 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 384 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 384 | ) | 385 | ) |
| 385 | .fail("Missing capability: allow-tip-sha1-in-want"); | 386 | .fail("Missing capability: allow-tip-sha1-in-want"); |
| @@ -387,7 +388,7 @@ impl GitCloneTests { | |||
| 387 | 388 | ||
| 388 | TestResult::new( | 389 | TestResult::new( |
| 389 | test_name, | 390 | test_name, |
| 390 | "GRASP-01:git-http:42", | 391 | SpecRef::GitIncludeAllowSha1InWant, |
| 391 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", | 392 | "MUST include allow-reachable-sha1-in-want and allow-tip-sha1-in-want in advertisement", |
| 392 | ) | 393 | ) |
| 393 | .pass() | 394 | .pass() |