Files
ngit-grasp/tests/purgatory_sync.rs
T
DanConwayDev 3de0156b2a Add integration test for git push triggering purgatory release
This test verifies the end-to-end flow where:
1. A state event is sent to the relay before git data exists
2. The event goes to purgatory (not served)
3. A git push delivers the required commits
4. The event is released from purgatory and served

This validates that process_newly_available_git_data is correctly
triggered after a git push and properly releases state events.
2026-01-07 14:58:59 +00:00

127 lines
4.2 KiB
Rust

//! Purgatory Sync Integration Tests
//!
//! Tests that verify purgatory sync behavior:
//! - Events entering purgatory are released when git data arrives
//! - Git push triggers unified processing
//! - Remote sync fetches git data and releases events
//!
//! # Test Strategy
//!
//! These tests verify the end-to-end purgatory flow:
//! 1. State/PR events go to purgatory when git data is missing
//! 2. Git push triggers `process_newly_available_git_data`
//! 3. Events are released from purgatory when git data becomes available
//!
//! # Running Tests
//!
//! ```bash
//! # Run all purgatory sync tests
//! cargo test --test purgatory_sync
//!
//! # Run specific test
//! cargo test --test purgatory_sync test_push_triggers_unified_processing
//!
//! # With output for debugging
//! cargo test --test purgatory_sync -- --nocapture
//! ```
mod common;
use common::{
create_repo_announcement, create_state_event, create_test_repo_with_commit, push_to_relay,
verify_event_not_served, wait_for_event_served, CommitVariant, TestRelay,
};
use nostr_sdk::prelude::*;
use std::time::Duration;
/// Test that a git push triggers `process_newly_available_git_data` and
/// releases state events from purgatory.
///
/// Scenario:
/// 1. Start relay
/// 2. Create and send repository announcement
/// 3. Create and send state event (goes to purgatory - no git data yet)
/// 4. Verify event is NOT served (in purgatory)
/// 5. Git push the required commit
/// 6. Verify event IS now served (released from purgatory)
#[tokio::test]
async fn test_push_triggers_unified_processing() {
// 1. Start relay
let relay = TestRelay::start().await;
let keys = Keys::generate();
let identifier = "push-test-repo";
// 2. Create test repository locally with deterministic commit
let temp_dir = tempfile::tempdir().expect("Failed to create temp dir");
let commit_hash =
create_test_repo_with_commit(temp_dir.path(), CommitVariant::StateTest)
.expect("Failed to create test repo");
// 3. Create and send announcement
let announcement = create_repo_announcement(&keys, &[&relay.domain()], identifier);
let client = Client::new(keys.clone());
client
.add_relay(relay.url())
.await
.expect("Failed to add relay");
client.connect().await;
// Wait for connection to be established
tokio::time::sleep(Duration::from_millis(500)).await;
// Send announcement
client
.send_event(&announcement)
.await
.expect("Failed to send announcement");
// Small delay to ensure announcement is processed
tokio::time::sleep(Duration::from_millis(200)).await;
// 4. Create and send state event referencing the commit
// The state event has refs that point to commits we haven't pushed yet
let npub = keys.public_key().to_bech32().expect("Failed to get npub");
let clone_url = format!("http://{}/{}/{}.git", relay.domain(), npub, identifier);
let state_event = create_state_event(
&keys,
identifier,
&[("main", &commit_hash)],
&[],
&[&clone_url],
&[relay.url()],
)
.expect("Failed to create state event");
let state_event_id = state_event.id;
client
.send_event(&state_event)
.await
.expect("Failed to send state event");
// 5. Verify event is NOT served yet (in purgatory)
// Give a moment for the event to be processed into purgatory
tokio::time::sleep(Duration::from_millis(200)).await;
verify_event_not_served(relay.url(), &state_event_id, Duration::from_secs(1))
.await
.expect("State event should NOT be served before git push (should be in purgatory)");
// 6. Git push to relay (this should trigger process_newly_available_git_data)
push_to_relay(temp_dir.path(), &relay.domain(), &npub, identifier)
.expect("Git push should succeed");
// 7. Verify event IS now served (released from purgatory)
let found_event = wait_for_event_served(relay.url(), &state_event_id, Duration::from_secs(5))
.await
.expect("State event should be served after git push");
// Verify it's the same event
assert_eq!(found_event.id, state_event_id);
// Cleanup
client.disconnect().await;
relay.stop().await;
}