diff options
Diffstat (limited to 'grasp-audit/src/specs/grasp01/event_acceptance_policy.rs')
| -rw-r--r-- | grasp-audit/src/specs/grasp01/event_acceptance_policy.rs | 165 |
1 files changed, 95 insertions, 70 deletions
diff --git a/grasp-audit/src/specs/grasp01/event_acceptance_policy.rs b/grasp-audit/src/specs/grasp01/event_acceptance_policy.rs index 5b697d8..3375c4d 100644 --- a/grasp-audit/src/specs/grasp01/event_acceptance_policy.rs +++ b/grasp-audit/src/specs/grasp01/event_acceptance_policy.rs | |||
| @@ -92,6 +92,7 @@ | |||
| 92 | //! - Transitive tests verify multi-hop acceptance chains | 92 | //! - Transitive tests verify multi-hop acceptance chains |
| 93 | 93 | ||
| 94 | use crate::fixtures::{send_and_verify_accepted, send_and_verify_rejected}; | 94 | use crate::fixtures::{send_and_verify_accepted, send_and_verify_rejected}; |
| 95 | use crate::specs::grasp01::SpecRef; | ||
| 95 | use crate::{AuditClient, AuditResult, FixtureKind, TestContext, TestResult}; | 96 | use crate::{AuditClient, AuditResult, FixtureKind, TestContext, TestResult}; |
| 96 | use nostr_sdk::{Event, Filter, Kind, Tag, TagKind, Timestamp, ToBech32}; | 97 | use nostr_sdk::{Event, Filter, Kind, Tag, TagKind, Timestamp, ToBech32}; |
| 97 | use std::time::Duration; | 98 | use std::time::Duration; |
| @@ -148,20 +149,23 @@ impl EventAcceptancePolicyTests { | |||
| 148 | pub async fn test_accept_valid_repo_announcement(client: &AuditClient) -> TestResult { | 149 | pub async fn test_accept_valid_repo_announcement(client: &AuditClient) -> TestResult { |
| 149 | TestResult::new( | 150 | TestResult::new( |
| 150 | "accept_valid_repo_announcement", | 151 | "accept_valid_repo_announcement", |
| 151 | "GRASP-01:nostr-relay:7", | 152 | SpecRef::NostrRelayNip01Compliant, |
| 152 | "Accept valid repository announcements with service in clone and relays tags", | 153 | "MUST accept repo announcements listing service in clone & relays tags", |
| 153 | ) | 154 | ) |
| 154 | .run(|| async { | 155 | .run(|| async { |
| 155 | // Create TestContext for mode-aware fixture management | 156 | // Create TestContext for mode-aware fixture management |
| 156 | let ctx = TestContext::new(client); | 157 | let ctx = TestContext::new(client); |
| 157 | 158 | ||
| 158 | // Request repository fixture - behavior depends on mode | 159 | // Request repository fixture - behavior depends on mode |
| 159 | let event = ctx.get_fixture(FixtureKind::ValidRepo).await.map_err(|e| { | 160 | let event = ctx |
| 160 | format!( | 161 | .get_fixture(FixtureKind::ValidRepoServed) |
| 161 | "Test setup failed: could not get valid repository fixture: {}", | 162 | .await |
| 162 | e | 163 | .map_err(|e| { |
| 163 | ) | 164 | format!( |
| 164 | })?; | 165 | "Test setup failed: could not get valid repository fixture: {}", |
| 166 | e | ||
| 167 | ) | ||
| 168 | })?; | ||
| 165 | 169 | ||
| 166 | // Get relay URL for validation | 170 | // Get relay URL for validation |
| 167 | let relay_url = client | 171 | let relay_url = client |
| @@ -253,8 +257,8 @@ impl EventAcceptancePolicyTests { | |||
| 253 | ) -> TestResult { | 257 | ) -> TestResult { |
| 254 | TestResult::new( | 258 | TestResult::new( |
| 255 | "reject_repo_announcement_missing_clone_tag", | 259 | "reject_repo_announcement_missing_clone_tag", |
| 256 | "GRASP-01:nostr-relay:9", | 260 | SpecRef::NostrRelayRejectMissingCloneRelays, |
| 257 | "Reject repository announcements without service in clone tag", | 261 | "MUST reject announcements not listing service in clone tag", |
| 258 | ) | 262 | ) |
| 259 | .run(|| async { | 263 | .run(|| async { |
| 260 | // Get relay URL from client | 264 | // Get relay URL from client |
| @@ -329,8 +333,8 @@ impl EventAcceptancePolicyTests { | |||
| 329 | ) -> TestResult { | 333 | ) -> TestResult { |
| 330 | TestResult::new( | 334 | TestResult::new( |
| 331 | "reject_repo_announcement_missing_relays_tag", | 335 | "reject_repo_announcement_missing_relays_tag", |
| 332 | "GRASP-01:nostr-relay:9", | 336 | SpecRef::NostrRelayRejectMissingCloneRelays, |
| 333 | "Reject repository announcements without service in relays tag", | 337 | "MUST reject announcements not listing service in relays tag", |
| 334 | ) | 338 | ) |
| 335 | .run(|| async { | 339 | .run(|| async { |
| 336 | // Get relay URL from client | 340 | // Get relay URL from client |
| @@ -425,8 +429,8 @@ impl EventAcceptancePolicyTests { | |||
| 425 | ) -> TestResult { | 429 | ) -> TestResult { |
| 426 | TestResult::new( | 430 | TestResult::new( |
| 427 | "accept_recursive_maintainer_announcement_without_service", | 431 | "accept_recursive_maintainer_announcement_without_service", |
| 428 | "GRASP-01:nostr-relay:9", | 432 | SpecRef::NostrRelayRejectMissingCloneRelays, |
| 429 | "Accept recursive maintainer announcement for chain discovery (even without GRASP server in clone)", | 433 | "MUST accept recursive maintainer announcements for chain discovery", |
| 430 | ) | 434 | ) |
| 431 | .run(|| async { | 435 | .run(|| async { |
| 432 | // Create TestContext for mode-aware fixture management | 436 | // Create TestContext for mode-aware fixture management |
| @@ -593,7 +597,7 @@ impl EventAcceptancePolicyTests { | |||
| 593 | pub async fn test_accept_issue_via_a_tag(client: &AuditClient) -> TestResult { | 597 | pub async fn test_accept_issue_via_a_tag(client: &AuditClient) -> TestResult { |
| 594 | TestResult::new( | 598 | TestResult::new( |
| 595 | "accept_issue_via_a_tag", | 599 | "accept_issue_via_a_tag", |
| 596 | "GRASP-01:nostr-relay:13", | 600 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 597 | "Accept issue referencing repo via 'a' tag", | 601 | "Accept issue referencing repo via 'a' tag", |
| 598 | ) | 602 | ) |
| 599 | .run(|| async { | 603 | .run(|| async { |
| @@ -601,12 +605,15 @@ impl EventAcceptancePolicyTests { | |||
| 601 | let ctx = TestContext::new(client); | 605 | let ctx = TestContext::new(client); |
| 602 | 606 | ||
| 603 | // NEW: Get repository fixture (mode-aware) | 607 | // NEW: Get repository fixture (mode-aware) |
| 604 | let repo = ctx.get_fixture(FixtureKind::ValidRepo).await.map_err(|e| { | 608 | let repo = ctx |
| 605 | format!( | 609 | .get_fixture(FixtureKind::ValidRepoServed) |
| 606 | "Test setup failed: could not get valid repository fixture: {}", | 610 | .await |
| 607 | e | 611 | .map_err(|e| { |
| 608 | ) | 612 | format!( |
| 609 | })?; | 613 | "Test setup failed: could not get valid repository fixture: {}", |
| 614 | e | ||
| 615 | ) | ||
| 616 | })?; | ||
| 610 | 617 | ||
| 611 | // 2. Create issue that references the repo | 618 | // 2. Create issue that references the repo |
| 612 | let issue = Self::create_issue_for_repo(client, &repo, "Test Issue 1")?; | 619 | let issue = Self::create_issue_for_repo(client, &repo, "Test Issue 1")?; |
| @@ -628,7 +635,7 @@ impl EventAcceptancePolicyTests { | |||
| 628 | pub async fn test_accept_comment_via_capital_a_tag(client: &AuditClient) -> TestResult { | 635 | pub async fn test_accept_comment_via_capital_a_tag(client: &AuditClient) -> TestResult { |
| 629 | TestResult::new( | 636 | TestResult::new( |
| 630 | "accept_comment_via_A_tag", | 637 | "accept_comment_via_A_tag", |
| 631 | "GRASP-01:nostr-relay:13", | 638 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 632 | "Accept NIP-22 comment with root 'A' tag referencing repo", | 639 | "Accept NIP-22 comment with root 'A' tag referencing repo", |
| 633 | ) | 640 | ) |
| 634 | .run(|| async { | 641 | .run(|| async { |
| @@ -636,12 +643,15 @@ impl EventAcceptancePolicyTests { | |||
| 636 | let ctx = TestContext::new(client); | 643 | let ctx = TestContext::new(client); |
| 637 | 644 | ||
| 638 | // Get repository fixture (mode-aware) | 645 | // Get repository fixture (mode-aware) |
| 639 | let repo = ctx.get_fixture(FixtureKind::ValidRepo).await.map_err(|e| { | 646 | let repo = ctx |
| 640 | format!( | 647 | .get_fixture(FixtureKind::ValidRepoServed) |
| 641 | "Test setup failed: could not get valid repository fixture: {}", | 648 | .await |
| 642 | e | 649 | .map_err(|e| { |
| 643 | ) | 650 | format!( |
| 644 | })?; | 651 | "Test setup failed: could not get valid repository fixture: {}", |
| 652 | e | ||
| 653 | ) | ||
| 654 | })?; | ||
| 645 | 655 | ||
| 646 | // Extract repo_id and create `A` tag manually | 656 | // Extract repo_id and create `A` tag manually |
| 647 | let repo_id = | 657 | let repo_id = |
| @@ -681,20 +691,23 @@ impl EventAcceptancePolicyTests { | |||
| 681 | pub async fn test_accept_kind1_via_q_tag(client: &AuditClient) -> TestResult { | 691 | pub async fn test_accept_kind1_via_q_tag(client: &AuditClient) -> TestResult { |
| 682 | TestResult::new( | 692 | TestResult::new( |
| 683 | "accept_kind1_via_q_tag", | 693 | "accept_kind1_via_q_tag", |
| 684 | "GRASP-01:nostr-relay:13", | 694 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 685 | "Accept kind 1 note quoting repo via 'q' tag", | 695 | "Accept kind 1 text note quoting repo via 'q' tag", |
| 686 | ) | 696 | ) |
| 687 | .run(|| async { | 697 | .run(|| async { |
| 688 | // Create TestContext | 698 | // Create TestContext |
| 689 | let ctx = TestContext::new(client); | 699 | let ctx = TestContext::new(client); |
| 690 | 700 | ||
| 691 | // Get repository fixture (mode-aware) | 701 | // Get repository fixture (mode-aware) |
| 692 | let repo = ctx.get_fixture(FixtureKind::ValidRepo).await.map_err(|e| { | 702 | let repo = ctx |
| 693 | format!( | 703 | .get_fixture(FixtureKind::ValidRepoServed) |
| 694 | "Test setup failed: could not get valid repository fixture: {}", | 704 | .await |
| 695 | e | 705 | .map_err(|e| { |
| 696 | ) | 706 | format!( |
| 697 | })?; | 707 | "Test setup failed: could not get valid repository fixture: {}", |
| 708 | e | ||
| 709 | ) | ||
| 710 | })?; | ||
| 698 | 711 | ||
| 699 | // Extract repo_id and create `q` tag | 712 | // Extract repo_id and create `q` tag |
| 700 | let repo_id = | 713 | let repo_id = |
| @@ -731,8 +744,8 @@ impl EventAcceptancePolicyTests { | |||
| 731 | pub async fn test_accept_issue_quoting_issue_via_q(client: &AuditClient) -> TestResult { | 744 | pub async fn test_accept_issue_quoting_issue_via_q(client: &AuditClient) -> TestResult { |
| 732 | TestResult::new( | 745 | TestResult::new( |
| 733 | "accept_issue_quoting_issue_via_q", | 746 | "accept_issue_quoting_issue_via_q", |
| 734 | "GRASP-01:nostr-relay:13", | 747 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 735 | "Accept issue quoting accepted issue (transitive)", | 748 | "Accept issue quoting another accepted issue (transitive)", |
| 736 | ) | 749 | ) |
| 737 | .run(|| async { | 750 | .run(|| async { |
| 738 | // Create TestContext | 751 | // Create TestContext |
| @@ -777,7 +790,7 @@ impl EventAcceptancePolicyTests { | |||
| 777 | pub async fn test_accept_comment_via_capital_e_tag(client: &AuditClient) -> TestResult { | 790 | pub async fn test_accept_comment_via_capital_e_tag(client: &AuditClient) -> TestResult { |
| 778 | TestResult::new( | 791 | TestResult::new( |
| 779 | "accept_comment_via_E_tag", | 792 | "accept_comment_via_E_tag", |
| 780 | "GRASP-01:nostr-relay:13", | 793 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 781 | "Accept NIP-22 comment with root 'E' tag to accepted issue", | 794 | "Accept NIP-22 comment with root 'E' tag to accepted issue", |
| 782 | ) | 795 | ) |
| 783 | .run(|| async { | 796 | .run(|| async { |
| @@ -816,7 +829,7 @@ impl EventAcceptancePolicyTests { | |||
| 816 | pub async fn test_accept_kind1_via_e_tag(client: &AuditClient) -> TestResult { | 829 | pub async fn test_accept_kind1_via_e_tag(client: &AuditClient) -> TestResult { |
| 817 | TestResult::new( | 830 | TestResult::new( |
| 818 | "accept_kind1_via_e_tag", | 831 | "accept_kind1_via_e_tag", |
| 819 | "GRASP-01:nostr-relay:13", | 832 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 820 | "Accept kind 1 reply via 'e' tag to accepted kind 1", | 833 | "Accept kind 1 reply via 'e' tag to accepted kind 1", |
| 821 | ) | 834 | ) |
| 822 | .run(|| async { | 835 | .run(|| async { |
| @@ -824,12 +837,15 @@ impl EventAcceptancePolicyTests { | |||
| 824 | let ctx = TestContext::new(client); | 837 | let ctx = TestContext::new(client); |
| 825 | 838 | ||
| 826 | // Get repository fixture (mode-aware) | 839 | // Get repository fixture (mode-aware) |
| 827 | let repo = ctx.get_fixture(FixtureKind::ValidRepo).await.map_err(|e| { | 840 | let repo = ctx |
| 828 | format!( | 841 | .get_fixture(FixtureKind::ValidRepoServed) |
| 829 | "Test setup failed: could not get valid repository fixture: {}", | 842 | .await |
| 830 | e | 843 | .map_err(|e| { |
| 831 | ) | 844 | format!( |
| 832 | })?; | 845 | "Test setup failed: could not get valid repository fixture: {}", |
| 846 | e | ||
| 847 | ) | ||
| 848 | })?; | ||
| 833 | 849 | ||
| 834 | // Create Kind 1 A that quotes the repo (makes it accepted) | 850 | // Create Kind 1 A that quotes the repo (makes it accepted) |
| 835 | let repo_id = Self::extract_d_tag(&repo).ok_or("Failed to extract repo_id")?; | 851 | let repo_id = Self::extract_d_tag(&repo).ok_or("Failed to extract repo_id")?; |
| @@ -872,7 +888,7 @@ impl EventAcceptancePolicyTests { | |||
| 872 | pub async fn test_accept_kind1_referenced_in_issue(client: &AuditClient) -> TestResult { | 888 | pub async fn test_accept_kind1_referenced_in_issue(client: &AuditClient) -> TestResult { |
| 873 | TestResult::new( | 889 | TestResult::new( |
| 874 | "accept_kind1_referenced_in_issue", | 890 | "accept_kind1_referenced_in_issue", |
| 875 | "GRASP-01:nostr-relay:13", | 891 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 876 | "Accept kind 1 referenced in accepted issue (forward ref)", | 892 | "Accept kind 1 referenced in accepted issue (forward ref)", |
| 877 | ) | 893 | ) |
| 878 | .run(|| async { | 894 | .run(|| async { |
| @@ -880,12 +896,15 @@ impl EventAcceptancePolicyTests { | |||
| 880 | let ctx = TestContext::new(client); | 896 | let ctx = TestContext::new(client); |
| 881 | 897 | ||
| 882 | // Get repository fixture (mode-aware) | 898 | // Get repository fixture (mode-aware) |
| 883 | let repo = ctx.get_fixture(FixtureKind::ValidRepo).await.map_err(|e| { | 899 | let repo = ctx |
| 884 | format!( | 900 | .get_fixture(FixtureKind::ValidRepoServed) |
| 885 | "Test setup failed: could not get valid repository fixture: {}", | 901 | .await |
| 886 | e | 902 | .map_err(|e| { |
| 887 | ) | 903 | format!( |
| 888 | })?; | 904 | "Test setup failed: could not get valid repository fixture: {}", |
| 905 | e | ||
| 906 | ) | ||
| 907 | })?; | ||
| 889 | 908 | ||
| 890 | // Verify repo is queryable (ensures it's fully indexed before we reference it) | 909 | // Verify repo is queryable (ensures it's fully indexed before we reference it) |
| 891 | let repo_id = Self::extract_d_tag(&repo).ok_or("Failed to extract repo_id")?; | 910 | let repo_id = Self::extract_d_tag(&repo).ok_or("Failed to extract repo_id")?; |
| @@ -964,7 +983,7 @@ impl EventAcceptancePolicyTests { | |||
| 964 | pub async fn test_accept_comment_referenced_in_comment(client: &AuditClient) -> TestResult { | 983 | pub async fn test_accept_comment_referenced_in_comment(client: &AuditClient) -> TestResult { |
| 965 | TestResult::new( | 984 | TestResult::new( |
| 966 | "accept_comment_referenced_in_comment", | 985 | "accept_comment_referenced_in_comment", |
| 967 | "GRASP-01:nostr-relay:13", | 986 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 968 | "Accept comment referenced in another accepted comment (forward ref)", | 987 | "Accept comment referenced in another accepted comment (forward ref)", |
| 969 | ) | 988 | ) |
| 970 | .run(|| async { | 989 | .run(|| async { |
| @@ -1025,7 +1044,7 @@ impl EventAcceptancePolicyTests { | |||
| 1025 | pub async fn test_accept_kind1_referenced_in_kind1(client: &AuditClient) -> TestResult { | 1044 | pub async fn test_accept_kind1_referenced_in_kind1(client: &AuditClient) -> TestResult { |
| 1026 | TestResult::new( | 1045 | TestResult::new( |
| 1027 | "accept_kind1_referenced_in_kind1", | 1046 | "accept_kind1_referenced_in_kind1", |
| 1028 | "GRASP-01:nostr-relay:13", | 1047 | SpecRef::NostrRelayMustAcceptTaggedEvents, |
| 1029 | "Accept kind 1 referenced in another accepted kind 1 (forward ref)", | 1048 | "Accept kind 1 referenced in another accepted kind 1 (forward ref)", |
| 1030 | ) | 1049 | ) |
| 1031 | .run(|| async { | 1050 | .run(|| async { |
| @@ -1033,12 +1052,15 @@ impl EventAcceptancePolicyTests { | |||
| 1033 | let ctx = TestContext::new(client); | 1052 | let ctx = TestContext::new(client); |
| 1034 | 1053 | ||
| 1035 | // Get repository fixture (mode-aware) | 1054 | // Get repository fixture (mode-aware) |
| 1036 | let repo = ctx.get_fixture(FixtureKind::ValidRepo).await.map_err(|e| { | 1055 | let repo = ctx |
| 1037 | format!( | 1056 | .get_fixture(FixtureKind::ValidRepoServed) |
| 1038 | "Test setup failed: could not get valid repository fixture: {}", | 1057 | .await |
| 1039 | e | 1058 | .map_err(|e| { |
| 1040 | ) | 1059 | format!( |
| 1041 | })?; | 1060 | "Test setup failed: could not get valid repository fixture: {}", |
| 1061 | e | ||
| 1062 | ) | ||
| 1063 | })?; | ||
| 1042 | 1064 | ||
| 1043 | // Create Kind 1 A locally but DON'T send it yet | 1065 | // Create Kind 1 A locally but DON'T send it yet |
| 1044 | let kind1_a = client | 1066 | let kind1_a = client |
| @@ -1083,7 +1105,7 @@ impl EventAcceptancePolicyTests { | |||
| 1083 | pub async fn test_reject_orphan_issue(client: &AuditClient) -> TestResult { | 1105 | pub async fn test_reject_orphan_issue(client: &AuditClient) -> TestResult { |
| 1084 | TestResult::new( | 1106 | TestResult::new( |
| 1085 | "reject_orphan_issue", | 1107 | "reject_orphan_issue", |
| 1086 | "GRASP-01:nostr-relay:18", | 1108 | SpecRef::NostrRelayMayRejectSpamCuration, |
| 1087 | "Reject issue referencing unaccepted repo", | 1109 | "Reject issue referencing unaccepted repo", |
| 1088 | ) | 1110 | ) |
| 1089 | .run(|| async { | 1111 | .run(|| async { |
| @@ -1110,7 +1132,7 @@ impl EventAcceptancePolicyTests { | |||
| 1110 | pub async fn test_reject_orphan_kind1(client: &AuditClient) -> TestResult { | 1132 | pub async fn test_reject_orphan_kind1(client: &AuditClient) -> TestResult { |
| 1111 | TestResult::new( | 1133 | TestResult::new( |
| 1112 | "reject_orphan_kind1", | 1134 | "reject_orphan_kind1", |
| 1113 | "GRASP-01:nostr-relay:18", | 1135 | SpecRef::NostrRelayMayRejectSpamCuration, |
| 1114 | "Reject kind 1 with no repo references", | 1136 | "Reject kind 1 with no repo references", |
| 1115 | ) | 1137 | ) |
| 1116 | .run(|| async { | 1138 | .run(|| async { |
| @@ -1139,7 +1161,7 @@ impl EventAcceptancePolicyTests { | |||
| 1139 | pub async fn test_reject_comment_quoting_other_repo(client: &AuditClient) -> TestResult { | 1161 | pub async fn test_reject_comment_quoting_other_repo(client: &AuditClient) -> TestResult { |
| 1140 | TestResult::new( | 1162 | TestResult::new( |
| 1141 | "reject_comment_quoting_other_repo", | 1163 | "reject_comment_quoting_other_repo", |
| 1142 | "GRASP-01:nostr-relay:18", | 1164 | SpecRef::NostrRelayMayRejectSpamCuration, |
| 1143 | "Reject comment quoting unaccepted repo", | 1165 | "Reject comment quoting unaccepted repo", |
| 1144 | ) | 1166 | ) |
| 1145 | .run(|| async { | 1167 | .run(|| async { |
| @@ -1147,12 +1169,15 @@ impl EventAcceptancePolicyTests { | |||
| 1147 | let ctx = TestContext::new(client); | 1169 | let ctx = TestContext::new(client); |
| 1148 | 1170 | ||
| 1149 | // Get accepted repo A fixture (mode-aware) | 1171 | // Get accepted repo A fixture (mode-aware) |
| 1150 | let _repo_a = ctx.get_fixture(FixtureKind::ValidRepo).await.map_err(|e| { | 1172 | let _repo_a = ctx |
| 1151 | format!( | 1173 | .get_fixture(FixtureKind::ValidRepoServed) |
| 1152 | "Test setup failed: could not get valid repository fixture: {}", | 1174 | .await |
| 1153 | e | 1175 | .map_err(|e| { |
| 1154 | ) | 1176 | format!( |
| 1155 | })?; | 1177 | "Test setup failed: could not get valid repository fixture: {}", |
| 1178 | e | ||
| 1179 | ) | ||
| 1180 | })?; | ||
| 1156 | 1181 | ||
| 1157 | // Create Repo B but DON'T send it (unaccepted) | 1182 | // Create Repo B but DON'T send it (unaccepted) |
| 1158 | let repo_b = Self::create_test_repo(client, "unaccepted-repo-b").await?; | 1183 | let repo_b = Self::create_test_repo(client, "unaccepted-repo-b").await?; |