mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-06 15:38:25 +00:00
test(deletion): add served PR-chain cascade coverage
This commit is contained in:
@@ -1,17 +1,19 @@
|
||||
//! NIP-09 announcement cascade coverage across supported dependent kinds.
|
||||
//!
|
||||
//! Covered here (single-maintainer): patch (1617), issue (1621), issue-status
|
||||
//! (1630), comment (1111), repo-status (1633).
|
||||
//!
|
||||
//! Not covered here: PR/PR-update/status chain (1618/1619/1631/1632), because
|
||||
//! those events require additional PR-specific git wiring and acceptance setup.
|
||||
//! (1630), comment (1111), repo-status (1633), PR chain
|
||||
//! (1618/1619/1631/1632).
|
||||
|
||||
mod common;
|
||||
|
||||
use common::{announcement_coordinate, build_deletion, publish_served_repo, TestRelay};
|
||||
use common::{
|
||||
announcement_coordinate, build_deletion, create_pr_event, publish_served_repo,
|
||||
push_ref_to_relay, TestRelay,
|
||||
};
|
||||
|
||||
use grasp_audit::{AuditClient, AuditConfig};
|
||||
use grasp_audit::{clone_repo, AuditClient, AuditConfig, DETERMINISTIC_COMMIT_HASH};
|
||||
use nostr_sdk::prelude::*;
|
||||
use std::fs;
|
||||
use std::time::Duration;
|
||||
|
||||
#[tokio::test]
|
||||
@@ -107,3 +109,131 @@ async fn test_announcement_cascade_deletes_supported_dependent_kinds() {
|
||||
"announcement deletion should cascade across covered dependent kinds; survivors: {survivors:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_announcement_cascade_deletes_served_pr_chain_kinds() {
|
||||
let relay = TestRelay::start().await;
|
||||
let client = AuditClient::new(relay.url(), AuditConfig::isolated())
|
||||
.await
|
||||
.expect("create audit client");
|
||||
let keys = client.keys().clone();
|
||||
|
||||
let relay_url = client
|
||||
.relay_url()
|
||||
.await
|
||||
.expect("client should have relay url");
|
||||
let relay_domain = relay_url
|
||||
.trim_start_matches("ws://")
|
||||
.trim_start_matches("wss://")
|
||||
.to_string();
|
||||
let npub = client.public_key().to_bech32().expect("pubkey to bech32");
|
||||
|
||||
let (announcement, repo_id) = publish_served_repo(&client, "cascade-pr-chain").await;
|
||||
let coordinate = announcement_coordinate(&announcement, &repo_id);
|
||||
|
||||
let pr = create_pr_event(&keys, &coordinate, DETERMINISTIC_COMMIT_HASH, "cascade pr")
|
||||
.expect("build PR event");
|
||||
client
|
||||
.send_event(pr.clone())
|
||||
.await
|
||||
.expect("relay should accept PR event");
|
||||
|
||||
let pr_update = client
|
||||
.event_builder(Kind::GitPullRequestUpdate, "cascade pr update")
|
||||
.tag(Tag::custom("a", vec![coordinate.clone()]))
|
||||
.tag(Tag::custom("e", vec![pr.id.to_hex()]))
|
||||
.tag(Tag::custom("c", vec![DETERMINISTIC_COMMIT_HASH.to_string()]))
|
||||
.build(&keys)
|
||||
.expect("build PR update event");
|
||||
client
|
||||
.send_event(pr_update.clone())
|
||||
.await
|
||||
.expect("relay should accept PR update event");
|
||||
|
||||
let clone_path = clone_repo(&relay_domain, &npub, &repo_id).expect("clone served repo");
|
||||
let pr_ref = format!("refs/nostr/{}", pr.id.to_hex());
|
||||
let pr_update_ref = format!("refs/nostr/{}", pr_update.id.to_hex());
|
||||
push_ref_to_relay(
|
||||
clone_path.as_path(),
|
||||
&relay_domain,
|
||||
&npub,
|
||||
&repo_id,
|
||||
DETERMINISTIC_COMMIT_HASH,
|
||||
&pr_ref,
|
||||
)
|
||||
.expect("push PR ref should succeed");
|
||||
push_ref_to_relay(
|
||||
clone_path.as_path(),
|
||||
&relay_domain,
|
||||
&npub,
|
||||
&repo_id,
|
||||
DETERMINISTIC_COMMIT_HASH,
|
||||
&pr_update_ref,
|
||||
)
|
||||
.expect("push PR update ref should succeed");
|
||||
fs::remove_dir_all(&clone_path).expect("remove cloned repo");
|
||||
|
||||
let pr_status = client
|
||||
.event_builder(Kind::from(1631), "pr status")
|
||||
.tag(Tag::custom("e", vec![pr.id.to_hex()]))
|
||||
.build(&keys)
|
||||
.expect("build PR status");
|
||||
let patch_status = client
|
||||
.event_builder(Kind::from(1632), "patch status")
|
||||
.tag(Tag::custom("e", vec![pr_update.id.to_hex()]))
|
||||
.build(&keys)
|
||||
.expect("build patch status");
|
||||
|
||||
for event in [&pr_status, &patch_status] {
|
||||
client
|
||||
.send_event(event.clone())
|
||||
.await
|
||||
.expect("relay should accept status event");
|
||||
}
|
||||
|
||||
tokio::time::sleep(Duration::from_millis(600)).await;
|
||||
|
||||
let cascade_chain = [
|
||||
("announcement", announcement.id),
|
||||
("pr", pr.id),
|
||||
("pr_update", pr_update.id),
|
||||
("pr_status", pr_status.id),
|
||||
("patch_status", patch_status.id),
|
||||
];
|
||||
|
||||
for (label, id) in cascade_chain {
|
||||
assert!(
|
||||
client
|
||||
.is_event_on_relay(id)
|
||||
.await
|
||||
.expect("query event before deletion"),
|
||||
"{label} ({id}) must be served before deletion"
|
||||
);
|
||||
}
|
||||
|
||||
let deletion = build_deletion(&client, &[], std::slice::from_ref(&coordinate));
|
||||
client
|
||||
.send_event(deletion)
|
||||
.await
|
||||
.expect("relay should accept announcement deletion");
|
||||
|
||||
tokio::time::sleep(Duration::from_millis(700)).await;
|
||||
|
||||
let mut survivors = Vec::new();
|
||||
for (label, id) in cascade_chain {
|
||||
let served = client
|
||||
.is_event_on_relay(id)
|
||||
.await
|
||||
.expect("query event after deletion");
|
||||
if served {
|
||||
survivors.push(format!("{label} ({id})"));
|
||||
}
|
||||
}
|
||||
|
||||
relay.stop().await;
|
||||
|
||||
assert!(
|
||||
survivors.is_empty(),
|
||||
"announcement deletion should cascade across PR-chain dependent kinds; survivors: {survivors:?}"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user