mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 15:08:24 +00:00
121 lines
3.4 KiB
Rust
121 lines
3.4 KiB
Rust
//! NIP-01 Compliance Integration Tests
|
|
//!
|
|
//! Tests ngit-grasp relay's NIP-01 compliance using grasp-audit library.
|
|
//! Uses isolated test pattern for complete test independence.
|
|
//!
|
|
//! # Test Strategy
|
|
//!
|
|
//! - 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
|
|
//!
|
|
//! ```bash
|
|
//! # Run all NIP-01 compliance tests
|
|
//! cargo test --test nip01_compliance
|
|
//!
|
|
//! # Run specific test
|
|
//! cargo test --test nip01_compliance test_websocket_connection
|
|
//!
|
|
//! # With output
|
|
//! cargo test --test nip01_compliance -- --nocapture
|
|
//! ```
|
|
|
|
mod common;
|
|
|
|
use common::TestRelay;
|
|
use grasp_audit::*;
|
|
|
|
/// Macro to generate isolated integration tests
|
|
///
|
|
/// 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::isolated();
|
|
let client = AuditClient::new(relay.url(), config)
|
|
.await
|
|
.expect("Failed to create audit client");
|
|
|
|
let result = specs::Nip01SmokeTests::$test_name(&client).await;
|
|
|
|
relay.stop().await;
|
|
|
|
assert!(
|
|
result.passed,
|
|
"{} failed: {}",
|
|
stringify!($test_name),
|
|
result.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
|
|
///
|
|
/// Verifies TestRelay 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::isolated();
|
|
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;
|
|
}
|
|
|
|
/// Test multiple relays can run in parallel
|
|
///
|
|
/// Ensures random port selection avoids conflicts
|
|
#[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::isolated();
|
|
|
|
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;
|
|
}
|