mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
test(relay): add public live control and search case for 44300 deletions
The non-owner live subscription now must receive a public deletion, so suppressing all kind:5 delivery to non-authors fails. Shared deletion helpers take the relay address from the including suite, so one binary never mixes two relays. Indexed deletion search now covers a k=44300 deletion. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
@@ -34,7 +34,9 @@ use serde_json::Value;
|
||||
mod support;
|
||||
use support::*;
|
||||
|
||||
const DEFAULT_RELAY_URL: &str = "ws://localhost:3001";
|
||||
const KIND_EVENT_REMINDER: u16 = 30300;
|
||||
const KIND_INSTRUCTIONS_VERSION: u16 = 44300;
|
||||
|
||||
fn build_reminder(keys: &Keys) -> nostr::Event {
|
||||
EventBuilder::new(
|
||||
@@ -68,6 +70,30 @@ async fn store_deleted_reminder(client: &Client, author: &Keys) -> (nostr::Event
|
||||
(reminder, deletion)
|
||||
}
|
||||
|
||||
/// Store and delete an instructions version (kind:44300) with a `k`-tagged
|
||||
/// deletion carrying `author`'s search term as its reason.
|
||||
async fn store_deleted_instructions_version(client: &Client, author: &Keys) -> nostr::Event {
|
||||
let subject = Keys::generate().public_key().to_hex();
|
||||
let version = EventBuilder::new(
|
||||
Kind::Custom(KIND_INSTRUCTIONS_VERSION),
|
||||
"AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
)
|
||||
.tags(vec![tag(&["p", &subject])])
|
||||
.sign_with_keys(author)
|
||||
.unwrap();
|
||||
submit_ok(client, author, &version).await;
|
||||
let deletion = build_deletion_with_reason(
|
||||
author,
|
||||
vec![
|
||||
tag(&["e", &version.id.to_hex()]),
|
||||
tag(&["k", &KIND_INSTRUCTIONS_VERSION.to_string()]),
|
||||
],
|
||||
&search_term(author),
|
||||
);
|
||||
submit_ok(client, author, &deletion).await;
|
||||
deletion
|
||||
}
|
||||
|
||||
/// A search term unique to `author`'s deletion reason.
|
||||
fn search_term(author: &Keys) -> String {
|
||||
format!("aodreason{}", &author.public_key().to_hex()[..16])
|
||||
@@ -104,6 +130,7 @@ async fn author_only_deletion_search_reaches_only_author() {
|
||||
let client = http_client();
|
||||
let author = Keys::generate();
|
||||
let (_, private) = store_deleted_reminder(&client, &author).await;
|
||||
let instructions = store_deleted_instructions_version(&client, &author).await;
|
||||
// Public control: an ordinary deletion carrying the same reason word.
|
||||
let note = EventBuilder::text_note("public note")
|
||||
.sign_with_keys(&author)
|
||||
@@ -119,14 +146,18 @@ async fn author_only_deletion_search_reaches_only_author() {
|
||||
let search = Filter::new()
|
||||
.kind(Kind::EventDeletion)
|
||||
.search(search_term(&author));
|
||||
let (private, public) = (private.id.to_hex(), public.id.to_hex());
|
||||
let (private, instructions, public) = (
|
||||
private.id.to_hex(),
|
||||
instructions.id.to_hex(),
|
||||
public.id.to_hex(),
|
||||
);
|
||||
let strict = search_indexes_deletions();
|
||||
let mut mismatches = Vec::new();
|
||||
for (reader, name, allowed) in [
|
||||
(
|
||||
&author,
|
||||
"author",
|
||||
BTreeSet::from([private.clone(), public.clone()]),
|
||||
BTreeSet::from([private.clone(), instructions.clone(), public.clone()]),
|
||||
),
|
||||
(&Keys::generate(), "other", BTreeSet::from([public.clone()])),
|
||||
] {
|
||||
|
||||
@@ -33,21 +33,12 @@ use serde_json::{json, Value};
|
||||
#[path = "support/author_only_deletion.rs"]
|
||||
mod aod;
|
||||
|
||||
const DEFAULT_RELAY_URL: &str = "ws://localhost:3000";
|
||||
const INSTRUCTIONS_VERSION_KIND: u16 = 44300;
|
||||
const MAX_CONTENT_BYTES: usize = 218_548;
|
||||
const CIPHERTEXT: &str = "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
|
||||
fn relay_url() -> String {
|
||||
std::env::var("RELAY_URL").unwrap_or_else(|_| "ws://localhost:3000".to_string())
|
||||
}
|
||||
|
||||
fn relay_http_url() -> String {
|
||||
relay_url()
|
||||
.replace("wss://", "https://")
|
||||
.replace("ws://", "http://")
|
||||
.trim_end_matches('/')
|
||||
.to_string()
|
||||
}
|
||||
use aod::{relay_http_url, relay_url};
|
||||
|
||||
fn sub_id(name: &str) -> String {
|
||||
format!("e2e-instr-{name}-{}", uuid::Uuid::new_v4())
|
||||
@@ -739,7 +730,8 @@ async fn test_instructions_version_deletion_reads_are_author_only() {
|
||||
}
|
||||
|
||||
/// Subscribed while the version still exists, the owner receives its
|
||||
/// deletion live and another reader does not.
|
||||
/// deletion live and another reader does not. A public deletion by the same
|
||||
/// owner is the positive control: both subscribers must receive it.
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn test_instructions_version_deletion_live_fanout_is_author_only() {
|
||||
@@ -774,23 +766,34 @@ async fn test_instructions_version_deletion_live_fanout_is_author_only() {
|
||||
],
|
||||
);
|
||||
aod::submit_ok(&client, &owner, &deletion).await;
|
||||
let note = EventBuilder::text_note("public note")
|
||||
.sign_with_keys(&owner)
|
||||
.unwrap();
|
||||
aod::submit_ok(&client, &owner, ¬e).await;
|
||||
let public = aod::build_deletion(
|
||||
&owner,
|
||||
vec![aod::tag(&["e", ¬e.id.to_hex()]), aod::tag(&["k", "1"])],
|
||||
);
|
||||
aod::submit_ok(&client, &owner, &public).await;
|
||||
|
||||
for (i, (mut ws, sid)) in subscribers.into_iter().enumerate() {
|
||||
let delivered = aod::live_event_ids(&mut ws, &sid)
|
||||
.await
|
||||
.contains(&deletion.id);
|
||||
let delivered = aod::live_event_ids(&mut ws, &sid).await;
|
||||
assert!(
|
||||
delivered.contains(&public.id),
|
||||
"public deletion must reach subscriber {i} (0 = owner)"
|
||||
);
|
||||
assert_eq!(
|
||||
delivered,
|
||||
delivered.contains(&deletion.id),
|
||||
i == 0,
|
||||
"live delivery to subscriber {i} (0 = owner)"
|
||||
"private deletion delivery to subscriber {i} (0 = owner)"
|
||||
);
|
||||
ws.disconnect().await.expect("disconnect");
|
||||
}
|
||||
}
|
||||
|
||||
/// A deletion of a version must carry `["k","44300"]`: one without it, or
|
||||
/// with another kind, is rejected whether the version is live or already
|
||||
/// deleted.
|
||||
/// A deletion of a version must carry `["k","44300"]`. While the version is
|
||||
/// live, a missing, wrong or noncanonical `k` is rejected; once it is
|
||||
/// deleted, a deletion without `k` is still rejected.
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn test_instructions_version_deletion_requires_k_tag() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
//! Shared helpers for NIP-09 deletion e2e tests of author-only kinds. Each
|
||||
//! test binary covering a kind in `AUTHOR_ONLY_KINDS` includes this module.
|
||||
//! test binary covering a kind in `AUTHOR_ONLY_KINDS` includes this module
|
||||
//! and defines `DEFAULT_RELAY_URL`, so the helpers and the including suite
|
||||
//! always talk to the same relay.
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::time::Duration;
|
||||
@@ -10,7 +12,7 @@ use reqwest::Client;
|
||||
use serde_json::Value;
|
||||
|
||||
pub fn relay_url() -> String {
|
||||
std::env::var("RELAY_URL").unwrap_or_else(|_| "ws://localhost:3001".to_string())
|
||||
std::env::var("RELAY_URL").unwrap_or_else(|_| super::DEFAULT_RELAY_URL.to_string())
|
||||
}
|
||||
|
||||
pub fn relay_http_url() -> String {
|
||||
|
||||
Reference in New Issue
Block a user