mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 15:08:24 +00:00
- 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
191 lines
5.3 KiB
Rust
191 lines
5.3 KiB
Rust
//! 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;
|
|
}
|