tangle


git clone https://radroots.dev/git/tangle.git
Log | Files | Refs | README | LICENSE

commit 2a1550d7e925c696dbe0502a357b748c6fd0212d
parent 8c1f1e034bf3833ee55ba651b591c4a2e29b2ca9
Author: triesap <tyson@radroots.org>
Date:   Fri,  5 Jun 2026 23:39:16 -0700

store-surreal: close strict coverage gaps

Diffstat:
Mcrates/tangle_store_surreal/src/lib.rs | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 192 insertions(+), 19 deletions(-)

diff --git a/crates/tangle_store_surreal/src/lib.rs b/crates/tangle_store_surreal/src/lib.rs @@ -903,11 +903,8 @@ impl SurrealStore { .map_err(SurrealStoreError::from)? .check() .map_err(SurrealStoreError::from)?; - let info: Option<surrealdb::types::Value> = - response.take(0).map_err(SurrealStoreError::from)?; - Ok(info - .map(|value| format!("{value:?}")) - .unwrap_or_else(|| "None".to_owned())) + let info: surrealdb::types::Value = response.take(0).map_err(SurrealStoreError::from)?; + Ok(format!("{info:?}")) } pub async fn store_raw_event( @@ -1136,9 +1133,7 @@ CREATE event_tag_index CONTENT { None => current, }); } - let Some(intersection) = intersection else { - return Ok(Vec::new()); - }; + let intersection = intersection.unwrap_or_default(); let mut result = first_order .into_iter() .filter(|event_id| intersection.contains(event_id)) @@ -1322,16 +1317,12 @@ UPSERT type::record('deletion_marker', $marker_id) CONTENT { .map_err(SurrealStoreError::from)? .check() .map_err(SurrealStoreError::from)?; - match target_type { - "event" => { - self.mark_raw_event_deleted(&target_ref, event.unsigned().pubkey().as_str()) - .await?; - } - "address" => { - self.mark_address_deleted(&target_ref, event.unsigned().pubkey().as_str()) - .await?; - } - _ => {} + if target_type == "event" { + self.mark_raw_event_deleted(&target_ref, event.unsigned().pubkey().as_str()) + .await?; + } else { + self.mark_address_deleted(&target_ref, event.unsigned().pubkey().as_str()) + .await?; } } Ok(DeletionMarkerOutcome::Applied { @@ -2434,8 +2425,9 @@ mod tests { ListingProjectionQuery, ListingRevisionOutcome, MigrationApplyOutcome, SearchDocumentOutcome, SearchDocumentQuery, SurrealConfigError, SurrealConnectionConfig, SurrealConnectionMode, SurrealMigration, SurrealMigrationError, SurrealMigrationPlan, - SurrealStore, base_migration_plan, migration_tracking_schema, + SurrealStore, SurrealStoreError, base_migration_plan, migration_tracking_schema, }; + use tangle_nips::ListingProjectionEvaluation; use tangle_protocol::{ Event, EventId, Kind, PublicKeyHex, SignatureHex, Tag, UnixTimestamp, UnsignedEvent, filter_from_value, @@ -3295,6 +3287,7 @@ mod tests { let intersection = filter_from_value(&serde_json::json!({ "#e": [target_event], "#p": [pubkey_a], + "authors": [pubkey_a], "kinds": [1], "since": 100, "until": 102 @@ -3876,6 +3869,48 @@ mod tests { assert_eq!(row["deleted"], false); assert_eq!(row["projected_at"], projected_at.as_u64()); + let media_listing = synthetic_event( + "6", + "8", + listing.unsigned().pubkey().as_str(), + 1_714_125_101, + 30_402, + vec![ + Tag::from_parts("d", &["listing-media"]).expect("d tag"), + Tag::from_parts("title", &["Media carrots"]).expect("title"), + Tag::from_parts("price", &["7.25", "USD"]).expect("price"), + Tag::from_parts("unit", &["lb"]).expect("unit"), + Tag::from_parts("fulfillment", &["pickup"]).expect("fulfillment"), + Tag::from_parts("published_at", &["1714125100"]).expect("published"), + Tag::from_parts( + "image", + &["https://fixtures.radroots.test/listing-media.png"], + ) + .expect("image"), + ], + "media listing", + ); + assert_eq!( + store + .project_current_listing(&media_listing, projected_at) + .await + .expect("media current"), + ListingCurrentOutcome::Projected + ); + let media_row = store + .listing_current_row(&format!( + "30402:{}:listing-media", + media_listing.unsigned().pubkey().as_str() + )) + .await + .expect("media row") + .expect("media row exists"); + assert_eq!(media_row["published_at"], 1_714_125_100_u64); + assert_eq!( + media_row["image_urls"][0], + "https://fixtures.radroots.test/listing-media.png" + ); + let pubkey = "d".repeat(PublicKeyHex::HEX_LENGTH); let invalid = synthetic_event( "e", @@ -4251,6 +4286,144 @@ mod tests { ); } + #[tokio::test] + async fn private_helpers_cover_debug_errors_and_decimal_edges() { + let store = memory_store().await; + assert!(format!("{store:?}").contains("SurrealStore")); + let source = store + .database() + .query("THIS IS NOT VALID SURQL") + .await + .expect_err("surreal error"); + assert!(!SurrealStoreError::from(source).message().is_empty()); + let note = synthetic_event( + "1", + "b", + &"1".repeat(PublicKeyHex::HEX_LENGTH), + 1, + 1, + Vec::new(), + "note", + ); + let fields = + super::listing_revision_fields(&note, &ListingProjectionEvaluation::NotListing) + .expect("not listing fields"); + assert_eq!(fields.revision_key, note.id().as_str()); + assert!(!fields.parsed_ok); + let pubkey = "2".repeat(PublicKeyHex::HEX_LENGTH); + let addressable_without_d = + synthetic_event("2", "c", &pubkey, 2, 30_402, Vec::new(), "addressless"); + assert_eq!( + super::address_key_value(&addressable_without_d) + .expect_err("address key error") + .message(), + "addressable event must include a d tag" + ); + assert_eq!( + store + .maintain_current_event(&addressable_without_d) + .await + .expect_err("current key error") + .message(), + "addressable event must include a d tag" + ); + let malformed_deletion = synthetic_event( + "3", + "d", + &pubkey, + 3, + 5, + vec![Tag::from_parts("e", &["not-hex"]).expect("e tag")], + "bad deletion", + ); + assert_eq!( + store + .apply_deletion_markers(&malformed_deletion) + .await + .expect_err("malformed deletion") + .message(), + "event id must be 64 characters, got 7" + ); + assert_eq!( + super::tag_values( + &synthetic_event( + "4", + "e", + &pubkey, + 4, + 1, + vec![ + Tag::from_parts("image", &["https://fixtures.radroots.test/helper.png"]) + .expect("image tag") + ], + "image helper", + ), + "image" + ), + vec!["https://fixtures.radroots.test/helper.png".to_owned()] + ); + assert_eq!( + super::unique_in_order(vec![ + "first".to_owned(), + "first".to_owned(), + "second".to_owned() + ]), + vec!["first".to_owned(), "second".to_owned()] + ); + assert_eq!(super::price_minor("12"), Some(1_200)); + assert_eq!(super::price_minor("1.2.3"), None); + assert_eq!(super::price_minor("1.234"), None); + } + + #[tokio::test] + async fn project_current_listing_rejects_prices_without_minor_unit_representation() { + let store = memory_store().await; + store + .apply_plan(&base_migration_plan()) + .await + .expect("apply plan"); + let pubkey = "1".repeat(PublicKeyHex::HEX_LENGTH); + let listing = synthetic_event( + "2", + "c", + &pubkey, + 1_714_125_500, + 30_402, + vec![ + Tag::from_parts("d", &["listing-fractional"]).expect("d tag"), + Tag::from_parts("title", &["Fractional carrots"]).expect("title"), + Tag::from_parts("price", &["1.234", "USD"]).expect("price"), + Tag::from_parts("unit", &["lb"]).expect("unit"), + Tag::from_parts("fulfillment", &["pickup"]).expect("fulfillment"), + ], + "fractional listing", + ); + + assert_eq!( + store + .store_listing_revision(&listing, UnixTimestamp::new(1_714_125_501)) + .await + .expect("revision"), + ListingRevisionOutcome::Stored { parsed_ok: true } + ); + assert_eq!( + store + .listing_revision_row(listing.id()) + .await + .expect("revision row") + .expect("revision exists")["price_minor"], + serde_json::Value::Null + ); + let error = store + .project_current_listing(&listing, UnixTimestamp::new(1_714_125_501)) + .await + .expect_err("minor unit error"); + assert_eq!( + error.message(), + "listing price amount must fit two decimal minor units" + ); + } + fn synthetic_event( id_digit: &str, sig_digit: &str,