mirror of
https://github.com/block/buzz.git
synced 2026-11-06 01:11:33 +00:00
Fix flaky DM resurface fence tests
The three Postgres fence tests in buzz-db asserted hidden_at equality against raw Utc::now() values, but timestamptz stores microsecond precision, so the nanosecond tail was truncated on round-trip and the equality assertions failed in CI. Truncate to microseconds up front. The e2e replay test (test_nipdv_message_replay_preserves_a_newer_rehide) posted two identical kind:41012 hides from B. A nostr event id is sha256 over second-resolution created_at, so when both hides land in the same wall-clock second they share an id and the relay dedupes the second one before re-running hide_dm -- B's re-hide silently vanished and the assertion saw an empty hidden set. Backdate the first hide to force distinct ids, matching the guard create_dm already uses. Both are test-authoring defects; the fence and resurface logic are unchanged. Co-authored-by: Mongo <9cfd347903944d5b85aa6c93d2ab67381b978a92a31914bca69998968752a1d7@buzz.block.builderlab.xyz> Signed-off-by: kenny lopez <klopez4212@gmail.com>
This commit is contained in:
@@ -614,6 +614,15 @@ mod tests {
|
||||
|
||||
const TEST_DB_URL: &str = "postgres://buzz:buzz_dev@localhost:5432/buzz";
|
||||
|
||||
/// Postgres `timestamptz` stores microsecond precision, so a raw
|
||||
/// `Utc::now()` (nanoseconds) will not round-trip equal. Truncate to
|
||||
/// microseconds up front so equality assertions compare like for like
|
||||
/// while the seconds-apart fence arithmetic stays intact.
|
||||
fn now_micros() -> DateTime<Utc> {
|
||||
use chrono::SubsecRound;
|
||||
Utc::now().trunc_subsecs(6)
|
||||
}
|
||||
|
||||
async fn setup_pool() -> PgPool {
|
||||
let database_url = std::env::var("BUZZ_TEST_DATABASE_URL")
|
||||
.or_else(|_| std::env::var("DATABASE_URL"))
|
||||
@@ -690,7 +699,7 @@ mod tests {
|
||||
.expect("create dm");
|
||||
|
||||
// Recipient hid the DM before the message was received.
|
||||
let hidden_at = Utc::now();
|
||||
let hidden_at = now_micros();
|
||||
set_hidden_at(&pool, community_id, dm.id, &recipient, hidden_at).await;
|
||||
let message_received_at = hidden_at + chrono::Duration::seconds(1);
|
||||
|
||||
@@ -725,7 +734,7 @@ mod tests {
|
||||
|
||||
// Recipient re-hid the DM on another device AFTER the message arrived
|
||||
// (e.g. a delayed replay of that message races the newer user action).
|
||||
let message_received_at = Utc::now();
|
||||
let message_received_at = now_micros();
|
||||
let hidden_at = message_received_at + chrono::Duration::seconds(1);
|
||||
set_hidden_at(&pool, community_id, dm.id, &recipient, hidden_at).await;
|
||||
|
||||
@@ -757,7 +766,7 @@ mod tests {
|
||||
.expect("create dm");
|
||||
|
||||
// Both participants have an old hide; only the recipient may be cleared.
|
||||
let hidden_at = Utc::now();
|
||||
let hidden_at = now_micros();
|
||||
set_hidden_at(&pool, community_id, dm.id, &sender, hidden_at).await;
|
||||
set_hidden_at(&pool, community_id, dm.id, &recipient, hidden_at).await;
|
||||
let message_received_at = hidden_at + chrono::Duration::seconds(1);
|
||||
|
||||
@@ -165,10 +165,27 @@ async fn create_dm(requester_keys: &Keys, other_pubkey_hex: &str) -> String {
|
||||
|
||||
/// Submit a signed command event via REST and assert it was accepted.
|
||||
async fn post_signed_event(keys: &Keys, kind: u16, tags: Vec<Tag>) {
|
||||
post_signed_event_created_at(keys, kind, tags, nostr::Timestamp::now()).await;
|
||||
}
|
||||
|
||||
/// Like [`post_signed_event`] but with an explicit `created_at`. A nostr event
|
||||
/// id is `sha256(pubkey, created_at, kind, tags, content)` at second
|
||||
/// resolution, so two otherwise-identical command events posted in the same
|
||||
/// wall-clock second collide on id and the relay dedupes the second one
|
||||
/// (`command_executor` returns `PersistResult::Duplicate` before re-running the
|
||||
/// mutation). Callers that must post the same command twice as distinct actions
|
||||
/// backdate the first to force distinct ids — the same guard `create_dm` uses.
|
||||
async fn post_signed_event_created_at(
|
||||
keys: &Keys,
|
||||
kind: u16,
|
||||
tags: Vec<Tag>,
|
||||
created_at: nostr::Timestamp,
|
||||
) {
|
||||
let client = reqwest::Client::new();
|
||||
let pubkey_hex = keys.public_key().to_hex();
|
||||
let event = EventBuilder::new(Kind::Custom(kind), "")
|
||||
.tags(tags)
|
||||
.custom_created_at(created_at)
|
||||
.sign_with_keys(keys)
|
||||
.unwrap();
|
||||
let resp = client
|
||||
@@ -1456,10 +1473,14 @@ async fn test_nipdv_message_replay_preserves_a_newer_rehide() {
|
||||
let channel_id = create_dm(&keys_a, &b_pubkey_hex).await;
|
||||
|
||||
// B hides the DM, then A sends a message. The message resurfaces it for B.
|
||||
post_signed_event(
|
||||
// Backdate this first hide so it cannot collide on event id with the
|
||||
// identical re-hide posted later in the same wall-clock second (which the
|
||||
// relay would dedupe, silently dropping the second hide).
|
||||
post_signed_event_created_at(
|
||||
&keys_b,
|
||||
41012,
|
||||
vec![Tag::parse(["h", &channel_id]).unwrap()],
|
||||
nostr::Timestamp::from(nostr::Timestamp::now().as_secs() - 10),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user