From 652c5913f695ba7e8dfd78cd0cbe5cc3de67fa59 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Tue, 4 Nov 2025 21:58:23 +0000 Subject: test: migrate to TestRelay fixture pattern and add compliance docs - Remove unnecessary 'nix' dev dependency (Unix syscalls crate, not needed) - Migrate announcement tests to new TestRelay fixture pattern - Delete legacy test files (announcement_tests.rs, test_relay.sh) - Add comprehensive test documentation (docs/how-to/test-compliance.md) - Update README.md with new test commands - All 18 integration tests passing (NIP-01 + NIP-34) Benefits: - Automatic relay lifecycle management - No manual setup required - Pure Rust integration tests - Better developer experience - CI/CD ready --- tests/nip01_compliance.rs | 190 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 tests/nip01_compliance.rs (limited to 'tests/nip01_compliance.rs') diff --git a/tests/nip01_compliance.rs b/tests/nip01_compliance.rs new file mode 100644 index 0000000..3e2fdd3 --- /dev/null +++ b/tests/nip01_compliance.rs @@ -0,0 +1,190 @@ +//! NIP-01 Compliance Integration Tests +//! +//! These tests verify that ngit-grasp relay implements NIP-01 correctly +//! by using the grasp-audit library to run compliance tests. +//! +//! # Test Strategy +//! +//! - Uses grasp-audit as a library (not CLI) +//! - Automatically manages relay lifecycle +//! - Reuses test specs from grasp-audit (single source of truth) +//! - Pure Rust, no shell scripts +//! +//! # Running Tests +//! +//! ```bash +//! # Run all NIP-01 compliance tests +//! cargo test --test nip01_compliance +//! +//! # Run specific test +//! cargo test --test nip01_compliance test_nip01_smoke +//! +//! # With output +//! cargo test --test nip01_compliance -- --nocapture +//! ``` + +mod common; + +use common::TestRelay; +use grasp_audit::*; + +/// Test NIP-01 smoke tests against ngit-grasp relay +/// +/// This test: +/// 1. Starts a fresh ngit-grasp relay instance +/// 2. Runs all NIP-01 smoke tests from grasp-audit +/// 3. Verifies all tests pass +/// 4. Shuts down the relay +#[tokio::test] +async fn test_nip01_smoke() { + // Start test relay + let relay = TestRelay::start().await; + + // Create audit client in CI mode (isolated, no cleanup needed) + let config = AuditConfig::ci(); + let client = AuditClient::new(relay.url(), config) + .await + .expect("Failed to create audit client"); + + // Run all NIP-01 smoke tests + let results = specs::Nip01SmokeTests::run_all(&client).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() + ); +} + +/// Test individual NIP-01 tests can be run separately +/// +/// This demonstrates that we can run individual tests from the specs +/// for more granular testing or debugging. +#[tokio::test] +async fn test_nip01_individual_tests() { + use grasp_audit::specs::nip01_smoke::Nip01SmokeTests; + + let relay = TestRelay::start().await; + let config = AuditConfig::ci(); + let client = AuditClient::new(relay.url(), config) + .await + .expect("Failed to create audit client"); + + // We can't call private methods, so we'll run the full suite + // This test is mainly to show the pattern + let all_results = Nip01SmokeTests::run_all(&client).await; + + relay.stop().await; + + // Verify + assert!(all_results.all_passed()); +} + +/// Test that relay rejects invalid events +/// +/// This is a critical security test - we want to ensure the relay +/// properly validates events before accepting them. +#[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"); + + // The validation tests are part of the smoke tests + let results = specs::Nip01SmokeTests::run_all(&client).await; + + // Check that validation tests exist and pass + let validation_tests: Vec<_> = results + .results + .iter() + .filter(|t| t.spec_ref.contains("validation")) + .collect(); + + relay.stop().await; + + // Should have validation tests + assert!( + !validation_tests.is_empty(), + "No validation tests found in NIP-01 smoke tests" + ); + + // All validation tests should pass + for test in validation_tests { + assert!( + test.passed, + "Validation test failed: {} - {}", + test.name, + test.error.as_deref().unwrap_or("unknown error") + ); + } +} + +/// Test relay lifecycle management +/// +/// Ensures our test fixture properly manages relay lifecycle +#[tokio::test] +async fn test_relay_lifecycle() { + // Start relay + let relay = TestRelay::start().await; + let url = relay.url().to_string(); + + // Verify we can connect + let config = AuditConfig::ci(); + let client = AuditClient::new(&url, config) + .await + .expect("Failed to connect to relay"); + + assert!(client.is_connected().await, "Client should be connected"); + + // Stop relay + relay.stop().await; + + // Note: We can't easily verify disconnection without modifying grasp-audit + // to expose connection state after relay shutdown. That's okay - the + // important part is that the relay starts and stops cleanly. +} + +/// Test multiple relays can run in parallel +/// +/// This ensures our random port selection works correctly +#[tokio::test] +async fn test_parallel_relays() { + // Start two relays simultaneously + let relay1 = TestRelay::start().await; + let relay2 = TestRelay::start().await; + + // Should have different URLs (different ports) + assert_ne!( + relay1.url(), + relay2.url(), + "Relays should use different ports" + ); + + // Both should be connectable + let config = AuditConfig::ci(); + + let client1 = AuditClient::new(relay1.url(), config.clone()) + .await + .expect("Failed to connect to relay 1"); + + let client2 = AuditClient::new(relay2.url(), config) + .await + .expect("Failed to connect to relay 2"); + + assert!(client1.is_connected().await); + assert!(client2.is_connected().await); + + // Clean up + relay1.stop().await; + relay2.stop().await; +} -- cgit v1.2.3