mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 23:18:24 +00:00
refactor: isolate each grasp-audit lib test with minimal boilerplate
- Add isolated_test! macro pattern to nip34_announcements.rs and nip01_compliance.rs - Each test runs with its own fresh relay instance for complete isolation - Make all individual test functions public in grasp-audit library (nip01_smoke.rs, event_acceptance_policy.rs) - Eliminates 122 lines of boilerplate across integration tests - Tests: 15 GRASP-01 event acceptance policy tests + 6 NIP-01 smoke tests - Ensures tests don't interfere with each other, preventing flakiness
This commit is contained in:
@@ -143,7 +143,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo for full isolation
|
||||
/// - In Production mode: Reuses cached repo to minimize events
|
||||
async fn test_accept_valid_repo_announcement(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_valid_repo_announcement(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_valid_repo_announcement",
|
||||
"GRASP-01:nostr-relay:3-5",
|
||||
@@ -246,7 +246,7 @@ impl EventAcceptancePolicyTests {
|
||||
///
|
||||
/// Spec: Line 5 of ../grasp/01.md
|
||||
/// Requirement: MUST reject announcements not listing service (unless GRASP-05)
|
||||
async fn test_reject_repo_announcement_missing_clone_tag(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_reject_repo_announcement_missing_clone_tag(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"reject_repo_announcement_missing_clone_tag",
|
||||
"GRASP-01:nostr-relay:5",
|
||||
@@ -320,7 +320,7 @@ impl EventAcceptancePolicyTests {
|
||||
///
|
||||
/// Spec: Line 5 of ../grasp/01.md
|
||||
/// Requirement: MUST reject announcements not listing service in relays
|
||||
async fn test_reject_repo_announcement_missing_relays_tag(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_reject_repo_announcement_missing_relays_tag(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"reject_repo_announcement_missing_relays_tag",
|
||||
"GRASP-01:nostr-relay:5",
|
||||
@@ -412,7 +412,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// This test demonstrates the new TestContext pattern:
|
||||
/// - In CI mode: Creates fresh repo for full isolation
|
||||
/// - In Production mode: Reuses cached repo to minimize events
|
||||
async fn test_accept_valid_repo_state_announcement(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_valid_repo_state_announcement(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_valid_repo_state_announcement",
|
||||
"GRASP-01:nostr-relay:6-7",
|
||||
@@ -579,7 +579,7 @@ impl EventAcceptancePolicyTests {
|
||||
///
|
||||
/// **EXAMPLE: Using TestContext for prerequisite events**
|
||||
/// Demonstrates how TestContext simplifies test setup while supporting dual modes
|
||||
async fn test_accept_issue_via_a_tag(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_issue_via_a_tag(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_issue_via_a_tag",
|
||||
"GRASP-01:event-acceptance:1.1",
|
||||
@@ -614,7 +614,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo for full isolation
|
||||
/// - In Production mode: Reuses cached repo to minimize events
|
||||
async fn test_accept_comment_via_capital_a_tag(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_comment_via_capital_a_tag(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_comment_via_A_tag",
|
||||
"GRASP-01:event-acceptance:1.2",
|
||||
@@ -666,7 +666,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo for full isolation
|
||||
/// - In Production mode: Reuses cached repo to minimize events
|
||||
async fn test_accept_kind1_via_q_tag(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_kind1_via_q_tag(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_kind1_via_q_tag",
|
||||
"GRASP-01:event-acceptance:1.3",
|
||||
@@ -715,7 +715,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo+issue for full isolation
|
||||
/// - In Production mode: Reuses cached repo+issue to minimize events
|
||||
async fn test_accept_issue_quoting_issue_via_q(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_issue_quoting_issue_via_q(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_issue_quoting_issue_via_q",
|
||||
"GRASP-01:event-acceptance:2.1",
|
||||
@@ -761,7 +761,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo+issue for full isolation
|
||||
/// - In Production mode: Reuses cached repo+issue to minimize events
|
||||
async fn test_accept_comment_via_capital_e_tag(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_comment_via_capital_e_tag(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_comment_via_E_tag",
|
||||
"GRASP-01:event-acceptance:2.2",
|
||||
@@ -799,7 +799,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo for full isolation
|
||||
/// - In Production mode: Reuses cached repo to minimize events
|
||||
async fn test_accept_kind1_via_e_tag(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_kind1_via_e_tag(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_kind1_via_e_tag",
|
||||
"GRASP-01:event-acceptance:2.3",
|
||||
@@ -859,7 +859,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo for full isolation
|
||||
/// - In Production mode: Reuses cached repo to minimize events
|
||||
async fn test_accept_kind1_referenced_in_issue(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_kind1_referenced_in_issue(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_kind1_referenced_in_issue",
|
||||
"GRASP-01:event-acceptance:3.1",
|
||||
@@ -928,7 +928,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo+issue for full isolation
|
||||
/// - In Production mode: Reuses cached repo+issue to minimize events
|
||||
async fn test_accept_comment_referenced_in_comment(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_comment_referenced_in_comment(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_comment_referenced_in_comment",
|
||||
"GRASP-01:event-acceptance:3.2",
|
||||
@@ -1010,7 +1010,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// **Using TestContext pattern:**
|
||||
/// - In CI mode: Creates fresh repo for full isolation
|
||||
/// - In Production mode: Reuses cached repo to minimize events
|
||||
async fn test_accept_kind1_referenced_in_kind1(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_accept_kind1_referenced_in_kind1(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"accept_kind1_referenced_in_kind1",
|
||||
"GRASP-01:event-acceptance:3.3",
|
||||
@@ -1070,7 +1070,7 @@ impl EventAcceptancePolicyTests {
|
||||
// ============================================================
|
||||
|
||||
/// Test 4.1: Issue referencing unaccepted repo should be rejected
|
||||
async fn test_reject_orphan_issue(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_reject_orphan_issue(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"reject_orphan_issue",
|
||||
"GRASP-01:event-acceptance:4.1",
|
||||
@@ -1098,7 +1098,7 @@ impl EventAcceptancePolicyTests {
|
||||
}
|
||||
|
||||
/// Test 4.2: Generic kind 1 note with no repo references should be rejected
|
||||
async fn test_reject_orphan_kind1(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_reject_orphan_kind1(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"reject_orphan_kind1",
|
||||
"GRASP-01:event-acceptance:4.2",
|
||||
@@ -1126,7 +1126,7 @@ impl EventAcceptancePolicyTests {
|
||||
/// - In CI mode: Creates fresh accepted repo for full isolation
|
||||
/// - In Production mode: Reuses cached accepted repo to minimize events
|
||||
/// - Note: Unaccepted repo B is always created fresh (not cached) since it must remain unaccepted
|
||||
async fn test_reject_comment_quoting_other_repo(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_reject_comment_quoting_other_repo(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"reject_comment_quoting_other_repo",
|
||||
"GRASP-01:event-acceptance:4.3",
|
||||
|
||||
@@ -29,7 +29,7 @@ impl Nip01SmokeTests {
|
||||
///
|
||||
/// Spec: NIP-01 basic requirement
|
||||
/// Requirement: MUST serve a relay at / via WebSocket
|
||||
async fn test_websocket_connection(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_websocket_connection(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"websocket_connection",
|
||||
"NIP-01:basic",
|
||||
@@ -52,7 +52,7 @@ impl Nip01SmokeTests {
|
||||
///
|
||||
/// For GRASP servers, we send a NIP-34 repository announcement that lists
|
||||
/// the GRASP server in clone and relays tags (required for acceptance).
|
||||
async fn test_send_receive_event(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_send_receive_event(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"send_receive_event",
|
||||
"NIP-01:event-message",
|
||||
@@ -123,7 +123,7 @@ impl Nip01SmokeTests {
|
||||
///
|
||||
/// Spec: NIP-01 REQ message
|
||||
/// Requirement: Relay MUST support REQ subscriptions
|
||||
async fn test_create_subscription(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_create_subscription(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"create_subscription",
|
||||
"NIP-01:req-message",
|
||||
@@ -165,7 +165,7 @@ impl Nip01SmokeTests {
|
||||
///
|
||||
/// Spec: NIP-01 CLOSE message
|
||||
/// Requirement: Relay MUST support CLOSE to end subscriptions
|
||||
async fn test_close_subscription(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_close_subscription(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"close_subscription",
|
||||
"NIP-01:close-message",
|
||||
@@ -193,7 +193,7 @@ impl Nip01SmokeTests {
|
||||
///
|
||||
/// Spec: NIP-01 event validation
|
||||
/// Requirement: Relay MUST reject events with invalid signatures
|
||||
async fn test_reject_invalid_signature(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_reject_invalid_signature(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"reject_invalid_signature",
|
||||
"NIP-01:validation",
|
||||
@@ -247,7 +247,7 @@ impl Nip01SmokeTests {
|
||||
///
|
||||
/// Spec: NIP-01 event ID validation
|
||||
/// Requirement: Relay MUST reject events where ID doesn't match hash
|
||||
async fn test_reject_invalid_event_id(client: &AuditClient) -> TestResult {
|
||||
pub async fn test_reject_invalid_event_id(client: &AuditClient) -> TestResult {
|
||||
TestResult::new(
|
||||
"reject_invalid_event_id",
|
||||
"NIP-01:validation",
|
||||
|
||||
+34
-80
@@ -1,13 +1,13 @@
|
||||
//! NIP-01 Compliance Integration Tests
|
||||
//!
|
||||
//! Tests ngit-grasp relay's NIP-01 compliance using grasp-audit library.
|
||||
//! Avoids code duplication by delegating to grasp-audit's test suite.
|
||||
//! Uses isolated test pattern for complete test independence.
|
||||
//!
|
||||
//! # Test Strategy
|
||||
//!
|
||||
//! - Uses TestRelay fixture for ngit-grasp relay lifecycle management
|
||||
//! - Uses grasp-audit's Nip01SmokeTests for actual test logic
|
||||
//! - Minimal duplication - single source of truth in grasp-audit
|
||||
//! - Each test runs in complete isolation with its own fresh relay instance
|
||||
//! - Uses macro to eliminate boilerplate while maintaining test isolation
|
||||
//! - Calls individual test methods from grasp-audit for minimal duplication
|
||||
//!
|
||||
//! # Running Tests
|
||||
//!
|
||||
@@ -16,7 +16,7 @@
|
||||
//! cargo test --test nip01_compliance
|
||||
//!
|
||||
//! # Run specific test
|
||||
//! cargo test --test nip01_compliance test_nip01_smoke
|
||||
//! cargo test --test nip01_compliance test_websocket_connection
|
||||
//!
|
||||
//! # With output
|
||||
//! cargo test --test nip01_compliance -- --nocapture
|
||||
@@ -27,87 +27,41 @@ mod common;
|
||||
use common::TestRelay;
|
||||
use grasp_audit::*;
|
||||
|
||||
/// Test NIP-01 smoke tests against ngit-grasp relay
|
||||
/// Macro to generate isolated integration tests
|
||||
///
|
||||
/// This test runs all NIP-01 smoke tests from grasp-audit against
|
||||
/// the ngit-grasp relay implementation.
|
||||
///
|
||||
/// Tests cover:
|
||||
/// - WebSocket connection
|
||||
/// - Event send/receive
|
||||
/// - Subscriptions (REQ/CLOSE)
|
||||
/// - Event validation (signature, ID)
|
||||
#[tokio::test]
|
||||
async fn test_nip01_smoke() {
|
||||
// Start test relay
|
||||
let relay = TestRelay::start().await;
|
||||
/// Each test runs with its own fresh relay instance to ensure complete isolation.
|
||||
/// This eliminates flakiness and ensures tests don't interfere with each other.
|
||||
macro_rules! isolated_test {
|
||||
($test_name:ident) => {
|
||||
#[tokio::test]
|
||||
async fn $test_name() {
|
||||
let relay = TestRelay::start().await;
|
||||
let config = AuditConfig::ci();
|
||||
let client = AuditClient::new(relay.url(), config)
|
||||
.await
|
||||
.expect("Failed to create audit client");
|
||||
|
||||
// Create audit client in CI mode (isolated testing)
|
||||
let config = AuditConfig::ci();
|
||||
let client = AuditClient::new(relay.url(), config)
|
||||
.await
|
||||
.expect("Failed to create audit client");
|
||||
let result = specs::Nip01SmokeTests::$test_name(&client).await;
|
||||
|
||||
// Run all NIP-01 smoke tests
|
||||
let results = specs::Nip01SmokeTests::run_all(&client).await;
|
||||
relay.stop().await;
|
||||
|
||||
// Print detailed report
|
||||
results.print_report();
|
||||
|
||||
// Stop relay
|
||||
relay.stop().await;
|
||||
|
||||
// Assert all tests passed
|
||||
assert!(
|
||||
results.all_passed(),
|
||||
"NIP-01 smoke tests failed: {}/{} passed",
|
||||
results.passed_count(),
|
||||
results.total_count()
|
||||
);
|
||||
assert!(
|
||||
result.passed,
|
||||
"{} failed: {}",
|
||||
stringify!($test_name),
|
||||
result.error.as_deref().unwrap_or("unknown error")
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Test that relay properly validates events
|
||||
///
|
||||
/// Critical security test - ensures relay validates:
|
||||
/// - Event signatures
|
||||
/// - Event IDs
|
||||
/// - Other NIP-01 requirements
|
||||
#[tokio::test]
|
||||
async fn test_relay_validates_events() {
|
||||
let relay = TestRelay::start().await;
|
||||
let config = AuditConfig::ci();
|
||||
let client = AuditClient::new(relay.url(), config)
|
||||
.await
|
||||
.expect("Failed to create audit client");
|
||||
|
||||
// Run smoke tests which include validation tests
|
||||
let results = specs::Nip01SmokeTests::run_all(&client).await;
|
||||
|
||||
relay.stop().await;
|
||||
|
||||
// Filter to validation tests
|
||||
let validation_tests: Vec<_> = results
|
||||
.results
|
||||
.iter()
|
||||
.filter(|t| t.name.contains("reject") || t.name.contains("invalid"))
|
||||
.collect();
|
||||
|
||||
// Should have validation tests
|
||||
assert!(
|
||||
!validation_tests.is_empty(),
|
||||
"No validation tests found (these are critical for security)"
|
||||
);
|
||||
|
||||
// All validation tests should pass
|
||||
for test in validation_tests {
|
||||
assert!(
|
||||
test.passed,
|
||||
"Validation test failed: {} - {}\nThis is a security issue!",
|
||||
test.name,
|
||||
test.error.as_deref().unwrap_or("unknown error")
|
||||
);
|
||||
}
|
||||
}
|
||||
// Generate isolated tests for all NIP-01 smoke tests
|
||||
isolated_test!(test_websocket_connection);
|
||||
isolated_test!(test_send_receive_event);
|
||||
isolated_test!(test_create_subscription);
|
||||
isolated_test!(test_close_subscription);
|
||||
isolated_test!(test_reject_invalid_signature);
|
||||
isolated_test!(test_reject_invalid_event_id);
|
||||
|
||||
/// Test relay lifecycle management
|
||||
///
|
||||
|
||||
+43
-119
@@ -5,9 +5,9 @@
|
||||
//!
|
||||
//! # Test Strategy
|
||||
//!
|
||||
//! - Uses TestRelay fixture for ngit-grasp relay lifecycle management
|
||||
//! - Uses grasp-audit's EventAcceptancePolicyTests for actual test logic
|
||||
//! - Minimal duplication - single source of truth in grasp-audit
|
||||
//! - Each test runs in complete isolation with its own fresh relay instance
|
||||
//! - Uses macro to eliminate boilerplate while maintaining test isolation
|
||||
//! - Calls individual test methods from grasp-audit for minimal duplication
|
||||
//!
|
||||
//! # Running Tests
|
||||
//!
|
||||
@@ -16,7 +16,7 @@
|
||||
//! cargo test --test nip34_announcements
|
||||
//!
|
||||
//! # Run specific test
|
||||
//! cargo test --test nip34_announcements test_grasp01_event_acceptance
|
||||
//! cargo test --test nip34_announcements test_reject_orphan_kind1
|
||||
//!
|
||||
//! # With output
|
||||
//! cargo test --test nip34_announcements -- --nocapture
|
||||
@@ -27,124 +27,48 @@ mod common;
|
||||
use common::TestRelay;
|
||||
use grasp_audit::*;
|
||||
|
||||
/// Test GRASP-01 event acceptance policy against ngit-grasp relay
|
||||
/// Macro to generate isolated integration tests
|
||||
///
|
||||
/// This test runs all GRASP-01 event acceptance policy tests from grasp-audit
|
||||
/// against the ngit-grasp relay implementation.
|
||||
///
|
||||
/// Tests cover:
|
||||
/// - Repository announcement acceptance/rejection
|
||||
/// - Repository state announcement acceptance
|
||||
/// - Events tagging accepted repositories
|
||||
/// - Transitive event acceptance (events tagging accepted events)
|
||||
/// - Forward reference acceptance (events tagged by accepted events)
|
||||
/// - Rejection of unrelated events
|
||||
#[tokio::test]
|
||||
async fn test_grasp01_event_acceptance() {
|
||||
// Start test relay
|
||||
let relay = TestRelay::start().await;
|
||||
/// Each test runs with its own fresh relay instance to ensure complete isolation.
|
||||
/// This eliminates rate-limiting issues and ensures tests don't interfere with each other.
|
||||
macro_rules! isolated_test {
|
||||
($test_name:ident) => {
|
||||
#[tokio::test]
|
||||
async fn $test_name() {
|
||||
let relay = TestRelay::start().await;
|
||||
let config = AuditConfig::ci();
|
||||
let client = AuditClient::new(relay.url(), config)
|
||||
.await
|
||||
.expect("Failed to create audit client");
|
||||
|
||||
// Create audit client in CI mode (isolated testing)
|
||||
let config = AuditConfig::ci();
|
||||
let client = AuditClient::new(relay.url(), config)
|
||||
.await
|
||||
.expect("Failed to create audit client");
|
||||
let result = specs::EventAcceptancePolicyTests::$test_name(&client).await;
|
||||
|
||||
// Run all GRASP-01 event acceptance policy tests
|
||||
let results = specs::EventAcceptancePolicyTests::run_all(&client).await;
|
||||
relay.stop().await;
|
||||
|
||||
// Print detailed report
|
||||
results.print_report();
|
||||
|
||||
// Stop relay
|
||||
relay.stop().await;
|
||||
|
||||
// Assert all tests passed
|
||||
assert!(
|
||||
results.all_passed(),
|
||||
"GRASP-01 event acceptance tests failed: {}/{} passed",
|
||||
results.passed_count(),
|
||||
results.total_count()
|
||||
);
|
||||
assert!(
|
||||
result.passed,
|
||||
"{} failed: {}",
|
||||
stringify!($test_name),
|
||||
result.error.as_deref().unwrap_or("unknown error")
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Test that relay accepts valid repository announcements
|
||||
///
|
||||
/// Demonstrates running individual test categories from the suite
|
||||
#[tokio::test]
|
||||
async fn test_accepts_repository_announcements() {
|
||||
let relay = TestRelay::start().await;
|
||||
let config = AuditConfig::ci();
|
||||
let client = AuditClient::new(relay.url(), config)
|
||||
.await
|
||||
.expect("Failed to create audit client");
|
||||
|
||||
// Run all tests
|
||||
let results = specs::EventAcceptancePolicyTests::run_all(&client).await;
|
||||
|
||||
relay.stop().await;
|
||||
|
||||
// Filter to only repository announcement tests
|
||||
let announcement_tests: Vec<_> = results
|
||||
.results
|
||||
.iter()
|
||||
.filter(|t| {
|
||||
t.spec_ref.contains("repo") || t.name.contains("announcement") || t.name.contains("state")
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Verify we have announcement tests
|
||||
assert!(
|
||||
!announcement_tests.is_empty(),
|
||||
"No repository announcement tests found"
|
||||
);
|
||||
|
||||
// All should pass
|
||||
for test in announcement_tests {
|
||||
assert!(
|
||||
test.passed,
|
||||
"Repository test failed: {} - {}",
|
||||
test.name,
|
||||
test.error.as_deref().unwrap_or("unknown error")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Test that relay properly validates clone and relays tags
|
||||
///
|
||||
/// This is a critical security requirement for GRASP-01
|
||||
#[tokio::test]
|
||||
async fn test_validates_service_tags() {
|
||||
let relay = TestRelay::start().await;
|
||||
let config = AuditConfig::ci();
|
||||
let client = AuditClient::new(relay.url(), config)
|
||||
.await
|
||||
.expect("Failed to create audit client");
|
||||
|
||||
let results = specs::EventAcceptancePolicyTests::run_all(&client).await;
|
||||
|
||||
relay.stop().await;
|
||||
|
||||
// Filter to rejection tests (these verify tag validation)
|
||||
let rejection_tests: Vec<_> = results
|
||||
.results
|
||||
.iter()
|
||||
.filter(|t| t.name.contains("reject"))
|
||||
.collect();
|
||||
|
||||
// Should have rejection tests
|
||||
assert!(
|
||||
!rejection_tests.is_empty(),
|
||||
"No rejection tests found (these are critical for security)"
|
||||
);
|
||||
|
||||
// All rejection tests should pass
|
||||
for test in rejection_tests {
|
||||
assert!(
|
||||
test.passed,
|
||||
"Rejection test failed: {} - {}\nThis is a security issue!",
|
||||
test.name,
|
||||
test.error.as_deref().unwrap_or("unknown error")
|
||||
);
|
||||
}
|
||||
}
|
||||
// Generate isolated tests for all GRASP-01 event acceptance policy tests
|
||||
isolated_test!(test_accept_valid_repo_announcement);
|
||||
isolated_test!(test_reject_repo_announcement_missing_clone_tag);
|
||||
isolated_test!(test_reject_repo_announcement_missing_relays_tag);
|
||||
isolated_test!(test_accept_valid_repo_state_announcement);
|
||||
isolated_test!(test_accept_issue_via_a_tag);
|
||||
isolated_test!(test_accept_comment_via_capital_a_tag);
|
||||
isolated_test!(test_accept_kind1_via_q_tag);
|
||||
isolated_test!(test_accept_issue_quoting_issue_via_q);
|
||||
isolated_test!(test_accept_comment_via_capital_e_tag);
|
||||
isolated_test!(test_accept_kind1_via_e_tag);
|
||||
isolated_test!(test_accept_kind1_referenced_in_issue);
|
||||
isolated_test!(test_accept_comment_referenced_in_comment);
|
||||
isolated_test!(test_accept_kind1_referenced_in_kind1);
|
||||
isolated_test!(test_reject_orphan_issue);
|
||||
isolated_test!(test_reject_orphan_kind1);
|
||||
isolated_test!(test_reject_comment_quoting_other_repo);
|
||||
Reference in New Issue
Block a user