upleb.uk

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

summaryrefslogtreecommitdiff
path: root/grasp-audit/src/specs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-02-13 10:29:16 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-02-13 12:31:48 +0000
commitd6b955104f4a04dcbe7324e9a861642f4654894f (patch)
tree01d6aeb07992780715b8c49bd1417953302e913b /grasp-audit/src/specs
parentf4e8e1089ae6e8e78c3576246d9747bb585fdc18 (diff)
refactor(grasp-audit): clarify PR purgatory test names and intent
- Remove redundant test_pr_event_remains_in_purgatory_until_git_data - Rename test_pr_event_git_push_accepted -> test_pr_event_in_purgatory_git_push_accepted - Add PASS/FAIL meaning to each test's documentation - Note black-box testing limitation for purgatory detection
Diffstat (limited to 'grasp-audit/src/specs')
-rw-r--r--grasp-audit/src/specs/grasp01/purgatory.rs109
1 files changed, 47 insertions, 62 deletions
diff --git a/grasp-audit/src/specs/grasp01/purgatory.rs b/grasp-audit/src/specs/grasp01/purgatory.rs
index 27ab97b..9c4b401 100644
--- a/grasp-audit/src/specs/grasp01/purgatory.rs
+++ b/grasp-audit/src/specs/grasp01/purgatory.rs
@@ -23,8 +23,9 @@
23//! - `test_state_event_served_after_git_push` 23//! - `test_state_event_served_after_git_push`
24//! 24//!
25//! ### PR Purgatory (already implemented) 25//! ### PR Purgatory (already implemented)
26//! - `test_pr_event_not_served_before_git_data` 26//! - `test_pr_event_accepted_into_purgatory` - Event accepted, not queryable
27//! - `test_pr_event_served_after_correct_push` 27//! - `test_pr_event_in_purgatory_git_push_accepted` - Git push to refs/nostr/<event-id> succeeds
28//! - `test_pr_event_served_after_git_push` - Event becomes queryable after git data
28 29
29use crate::specs::grasp01::SpecRef; 30use crate::specs::grasp01::SpecRef;
30use crate::{AuditClient, AuditResult, FixtureKind, TestContext, TestResult}; 31use crate::{AuditClient, AuditResult, FixtureKind, TestContext, TestResult};
@@ -50,9 +51,8 @@ impl PurgatoryTests {
50 results.add(Self::test_state_event_served_after_git_push(client).await); 51 results.add(Self::test_state_event_served_after_git_push(client).await);
51 52
52 // PR purgatory tests 53 // PR purgatory tests
53 results.add(Self::test_pr_event_before_git_data_accepted_into_purgatory(client).await); 54 results.add(Self::test_pr_event_accepted_into_purgatory_and_isnt_served(client).await);
54 results.add(Self::test_pr_event_remains_in_purgatory_until_git_data(client).await); 55 results.add(Self::test_pr_event_in_purgatory_git_push_accepted(client).await);
55 results.add(Self::test_pr_event_git_push_accepted(client).await);
56 results.add(Self::test_pr_event_served_after_git_push(client).await); 56 results.add(Self::test_pr_event_served_after_git_push(client).await);
57 57
58 results 58 results
@@ -507,32 +507,44 @@ impl PurgatoryTests {
507 // PR Purgatory Tests 507 // PR Purgatory Tests
508 // ============================================================ 508 // ============================================================
509 509
510 /// Test: PR event not served before git data arrives 510 /// Test: PR event accepted into purgatory (not served before git data)
511 /// 511 ///
512 /// Spec: GRASP-01 Line 22 512 /// Spec: GRASP-01 Line 22
513 /// "PRs and PR Updates SHOULD be accepted with message 513 /// "PRs and PR Updates SHOULD be accepted with message
514 /// 'purgatory: won't be served until git data arrives'" 514 /// 'purgatory: won't be served until git data arrives'"
515 /// 515 ///
516 /// This test verifies: 516 /// This test verifies:
517 /// 1. Send PR event for a repo 517 /// 1. PR event is sent and relay responds OK (accepted)
518 /// 2. PR event is NOT queryable (in purgatory) 518 /// 2. PR event is NOT queryable (in purgatory, not served)
519 /// 3. No git data exists at refs/nostr/<pr-event-id> 519 ///
520 pub async fn test_pr_event_before_git_data_accepted_into_purgatory( 520 /// PASS means: Relay accepted the event and is holding it in purgatory
521 /// FAIL means: Either event was rejected, or served immediately (purgatory not implemented)
522 ///
523 /// Note: This test cannot distinguish between "event in purgatory" and
524 /// "event accepted but never stored" - both result in event not being queryable.
525 /// The fixture verifies the relay responded OK, which is the best we can do
526 /// with black-box testing.
527 pub async fn test_pr_event_accepted_into_purgatory_and_isnt_served(
521 client: &AuditClient, 528 client: &AuditClient,
522 ) -> TestResult { 529 ) -> TestResult {
523 TestResult::new( 530 TestResult::new(
524 "pr_event_before_git_data_accepted_into_purgatory", 531 "pr_event_accepted_into_purgatory",
525 SpecRef::PurgatoryAcceptUntilGitData, 532 SpecRef::PurgatoryAcceptUntilGitData,
526 "PR event SHOULD be accepted into purgatory when git data doesn't exist", 533 "PR event SHOULD be accepted but not served until git data arrives",
527 ) 534 )
528 .run(|| async { 535 .run(|| async {
529 let ctx = TestContext::new(client); 536 let ctx = TestContext::new(client);
530 537
538 // PREvent2Sent fixture:
539 // 1. Sends PR event
540 // 2. Verifies relay responded OK (not rejected)
541 // 3. Verifies event is NOT queryable (in purgatory)
531 let pr_event = ctx 542 let pr_event = ctx
532 .get_fixture(FixtureKind::PREvent2Sent) 543 .get_fixture(FixtureKind::PREvent2Sent)
533 .await 544 .await
534 .map_err(|e| format!("Failed to send PR event: {}", e))?; 545 .map_err(|e| format!("Failed to send PR event: {}", e))?;
535 546
547 // Double-check: event should not be queryable
536 let filter = Filter::new() 548 let filter = Filter::new()
537 .kind(Kind::GitPullRequest) 549 .kind(Kind::GitPullRequest)
538 .author(client.pr_author_keys().public_key()) 550 .author(client.pr_author_keys().public_key())
@@ -547,7 +559,7 @@ impl PurgatoryTests {
547 559
548 if !events.is_empty() { 560 if !events.is_empty() {
549 return Err(format!( 561 return Err(format!(
550 "PR event was served immediately - should be in purgatory. Event ID: {}", 562 "PR event was served immediately - purgatory not implemented. Event ID: {}",
551 pr_event.id 563 pr_event.id
552 )); 564 ));
553 } 565 }
@@ -557,62 +569,26 @@ impl PurgatoryTests {
557 .await 569 .await
558 } 570 }
559 571
560 /// Test: PR event remains in purgatory until git data arrives 572 /// Test: Git push to refs/nostr/<pr-event-id> is accepted
561 /// 573 ///
562 /// Verifies the event stays in purgatory until matching git data is pushed. 574 /// This test verifies that pushing git data for a PR event in purgatory
563 pub async fn test_pr_event_remains_in_purgatory_until_git_data( 575 /// is accepted by the relay.
564 client: &AuditClient,
565 ) -> TestResult {
566 TestResult::new(
567 "pr_event_remains_in_purgatory_until_git_data",
568 SpecRef::PurgatoryAcceptUntilGitData,
569 "PR event SHOULD remain in purgatory until git data arrives",
570 )
571 .run(|| async {
572 let ctx = TestContext::new(client);
573
574 let pr_event = ctx
575 .get_fixture(FixtureKind::PREvent2Sent)
576 .await
577 .map_err(|e| format!("Failed to get PR event: {}", e))?;
578
579 tokio::time::sleep(Duration::from_millis(500)).await;
580
581 let filter = Filter::new()
582 .kind(Kind::GitPullRequest)
583 .author(client.pr_author_keys().public_key())
584 .id(pr_event.id);
585
586 let events = client
587 .query(filter)
588 .await
589 .map_err(|e| format!("Failed to query PR events: {}", e))?;
590
591 if !events.is_empty() {
592 return Err(format!(
593 "PR event was served without git data - purgatory not working. Event ID: {}",
594 pr_event.id
595 ));
596 }
597
598 Ok(())
599 })
600 .await
601 }
602
603 /// Test: Git push accepted for PR event in purgatory
604 /// 576 ///
605 /// Verifies that pushing the correct commit to refs/nostr/<pr-event-id> 577 /// PASS means: Git push succeeded, relay accepted the git data
606 /// is accepted. 578 /// FAIL means: Git push was rejected (wrong ref, permissions, etc.)
607 pub async fn test_pr_event_git_push_accepted(client: &AuditClient) -> TestResult { 579 pub async fn test_pr_event_in_purgatory_git_push_accepted(client: &AuditClient) -> TestResult {
608 TestResult::new( 580 TestResult::new(
609 "pr_event_git_push_accepted", 581 "pr_event_in_purgatory_git_push_accepted",
610 SpecRef::PurgatoryAcceptUntilGitData, 582 SpecRef::PurgatoryAcceptUntilGitData,
611 "Git push for PR event SHOULD be accepted", 583 "Git push for PR event SHOULD be accepted",
612 ) 584 )
613 .run(|| async { 585 .run(|| async {
614 let ctx = TestContext::new(client); 586 let ctx = TestContext::new(client);
615 587
588 // PREvent2GitDataPushed fixture:
589 // 1. Gets PR event in purgatory (PREvent2Sent)
590 // 2. Pushes commit to refs/nostr/<pr-event-id>
591 // 3. Verifies push succeeded
616 let _pr_event = ctx 592 let _pr_event = ctx
617 .get_fixture(FixtureKind::PREvent2GitDataPushed) 593 .get_fixture(FixtureKind::PREvent2GitDataPushed)
618 .await 594 .await
@@ -623,9 +599,14 @@ impl PurgatoryTests {
623 .await 599 .await
624 } 600 }
625 601
626 /// Test: PR event served after git push 602 /// Test: PR event served after git data arrives
603 ///
604 /// This test verifies the full purgatory release mechanism:
605 /// after git data is pushed to refs/nostr/<pr-event-id>, the event
606 /// becomes queryable.
627 /// 607 ///
628 /// Verifies the full purgatory release mechanism. 608 /// PASS means: Event was released from purgatory and is now served
609 /// FAIL means: Event still not queryable after git push (purgatory release broken)
629 pub async fn test_pr_event_served_after_git_push(client: &AuditClient) -> TestResult { 610 pub async fn test_pr_event_served_after_git_push(client: &AuditClient) -> TestResult {
630 TestResult::new( 611 TestResult::new(
631 "pr_event_served_after_git_push", 612 "pr_event_served_after_git_push",
@@ -635,11 +616,15 @@ impl PurgatoryTests {
635 .run(|| async { 616 .run(|| async {
636 let ctx = TestContext::new(client); 617 let ctx = TestContext::new(client);
637 618
619 // PREvent2Served fixture:
620 // 1. Gets PR event with git data pushed (PREvent2GitDataPushed)
621 // 2. Verifies event is now queryable
638 let pr_event = ctx 622 let pr_event = ctx
639 .get_fixture(FixtureKind::PREvent2Served) 623 .get_fixture(FixtureKind::PREvent2Served)
640 .await 624 .await
641 .map_err(|e| format!("Failed to complete purgatory release: {}", e))?; 625 .map_err(|e| format!("Failed to complete purgatory release: {}", e))?;
642 626
627 // Double-check: event should be queryable now
643 let filter = Filter::new() 628 let filter = Filter::new()
644 .kind(Kind::GitPullRequest) 629 .kind(Kind::GitPullRequest)
645 .author(client.pr_author_keys().public_key()) 630 .author(client.pr_author_keys().public_key())