lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 98f3202cffaf90d965fcdf6fd8325e7c298c653b
parent 8cb1c8788c6e28af22e1d10cb31d613340f75842
Author: triesap <tyson@radroots.org>
Date:   Tue, 23 Jun 2026 01:45:56 +0000

wasm: cover sdk wrapper logic

- remove dummy coverage probes from replica DB and sync WASM crates
- extract replica DB export snapshot policy into native-testable code
- cover replica sync request and event parsing across author and pubkey cases
- narrow the coverage contract to include the newly testable WASM source

Diffstat:
Mcrates/replica_sync_wasm/src/lib.rs | 99++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 71 insertions(+), 28 deletions(-)

diff --git a/crates/replica_sync_wasm/src/lib.rs b/crates/replica_sync_wasm/src/lib.rs @@ -1,20 +1,18 @@ -#![cfg(any(target_arch = "wasm32", coverage_nightly))] #![forbid(unsafe_code)] #[cfg(target_arch = "wasm32")] use base64::Engine; #[cfg(target_arch = "wasm32")] use base64::engine::general_purpose::URL_SAFE_NO_PAD; -#[cfg(target_arch = "wasm32")] use radroots_events::RadrootsNostrEvent; +use radroots_replica_sync::RadrootsReplicaSyncRequest; #[cfg(target_arch = "wasm32")] use radroots_replica_sync::{ - RadrootsReplicaIdFactory, RadrootsReplicaIngestOutcome, RadrootsReplicaSyncRequest, + RadrootsReplicaIdFactory, RadrootsReplicaIngestOutcome, radroots_replica_ingest_event_with_factory, radroots_replica_sync_all, }; #[cfg(target_arch = "wasm32")] use radroots_sdk_sql_wasm_runtime::WasmSqlExecutor; -#[cfg(target_arch = "wasm32")] use serde::Deserialize; #[cfg(target_arch = "wasm32")] use uuid::Uuid; @@ -37,7 +35,6 @@ impl RadrootsReplicaIdFactory for WasmIdFactory { } } -#[cfg(target_arch = "wasm32")] #[derive(Deserialize)] struct NostrEventEnvelope { id: String, @@ -52,21 +49,20 @@ struct NostrEventEnvelope { sig: String, } -#[cfg(target_arch = "wasm32")] -fn parse_request(request_json: &str) -> Result<RadrootsReplicaSyncRequest, JsValue> { - serde_json::from_str(request_json).map_err(err_js) +pub fn parse_request_model(request_json: &str) -> Result<RadrootsReplicaSyncRequest, String> { + serde_json::from_str(request_json).map_err(|error| error.to_string()) } -#[cfg(target_arch = "wasm32")] -fn parse_event(event_json: &str) -> Result<RadrootsNostrEvent, JsValue> { - let envelope: NostrEventEnvelope = serde_json::from_str(event_json).map_err(err_js)?; +pub fn parse_event_model(event_json: &str) -> Result<RadrootsNostrEvent, String> { + let envelope: NostrEventEnvelope = + serde_json::from_str(event_json).map_err(|error| error.to_string())?; let author = match (envelope.author, envelope.pubkey) { (Some(author), Some(pubkey)) if author != pubkey => { - return Err(JsValue::from_str("author/pubkey mismatch")); + return Err("author/pubkey mismatch".to_owned()); } (Some(author), _) => author, (None, Some(pubkey)) => pubkey, - (None, None) => return Err(JsValue::from_str("missing author/pubkey")), + (None, None) => return Err("missing author/pubkey".to_owned()), }; Ok(RadrootsNostrEvent { id: envelope.id, @@ -82,7 +78,7 @@ fn parse_event(event_json: &str) -> Result<RadrootsNostrEvent, JsValue> { #[cfg(target_arch = "wasm32")] #[wasm_bindgen(js_name = replica_sync_sync_all)] pub fn replica_sync_sync_all(request_json: &str) -> Result<JsValue, JsValue> { - let request = parse_request(request_json)?; + let request = parse_request_model(request_json).map_err(err_js)?; let exec = WasmSqlExecutor::new(); let bundle = radroots_replica_sync_all(&exec, &request).map_err(err_js)?; serde_wasm_bindgen::to_value(&bundle).map_err(err_js) @@ -91,7 +87,7 @@ pub fn replica_sync_sync_all(request_json: &str) -> Result<JsValue, JsValue> { #[cfg(target_arch = "wasm32")] #[wasm_bindgen(js_name = replica_sync_ingest_event)] pub fn replica_sync_ingest_event(event_json: &str) -> Result<JsValue, JsValue> { - let event = parse_event(event_json)?; + let event = parse_event_model(event_json).map_err(err_js)?; let exec = WasmSqlExecutor::new(); let factory = WasmIdFactory; let outcome = @@ -103,22 +99,69 @@ pub fn replica_sync_ingest_event(event_json: &str) -> Result<JsValue, JsValue> { Ok(JsValue::from_str(value)) } -#[cfg(coverage_nightly)] -pub fn coverage_branch_probe(input: bool) -> &'static str { - if input { - "replica-sync-wasm" - } else { - "replica-sync-wasm" +#[cfg(test)] +mod tests { + use super::{parse_event_model, parse_request_model}; + + fn event_json(author: Option<&str>, pubkey: Option<&str>) -> String { + let mut fields = vec![ + r#""id":"event-id""#.to_owned(), + r#""created_at":123"#.to_owned(), + r#""kind":30023"#.to_owned(), + r#""tags":[["d","one"]]"#.to_owned(), + r#""content":"content""#.to_owned(), + r#""sig":"sig""#.to_owned(), + ]; + if let Some(author) = author { + fields.push(format!(r#""author":"{author}""#)); + } + if let Some(pubkey) = pubkey { + fields.push(format!(r#""pubkey":"{pubkey}""#)); + } + format!("{{{}}}", fields.join(",")) } -} -#[cfg(all(test, coverage_nightly))] -mod tests { - use super::coverage_branch_probe; + #[test] + fn parse_event_accepts_matching_author_and_pubkey() { + let event = parse_event_model(&event_json(Some("author"), Some("author"))).expect("event"); + assert_eq!(event.author, "author"); + assert_eq!(event.tags, vec![vec!["d".to_owned(), "one".to_owned()]]); + } + + #[test] + fn parse_event_accepts_author_without_pubkey() { + let event = parse_event_model(&event_json(Some("author"), None)).expect("event"); + assert_eq!(event.author, "author"); + } + + #[test] + fn parse_event_accepts_pubkey_without_author() { + let event = parse_event_model(&event_json(None, Some("pubkey"))).expect("event"); + assert_eq!(event.author, "pubkey"); + } + + #[test] + fn parse_event_rejects_author_pubkey_mismatch() { + let error = + parse_event_model(&event_json(Some("author"), Some("pubkey"))).expect_err("error"); + assert_eq!(error, "author/pubkey mismatch"); + } + + #[test] + fn parse_event_rejects_missing_author_and_pubkey() { + let error = parse_event_model(&event_json(None, None)).expect_err("error"); + assert_eq!(error, "missing author/pubkey"); + } + + #[test] + fn parse_event_rejects_malformed_json() { + let error = parse_event_model("{").expect_err("error"); + assert!(error.contains("EOF")); + } #[test] - fn coverage_branch_probe_hits_both_paths() { - assert_eq!(coverage_branch_probe(true), "replica-sync-wasm"); - assert_eq!(coverage_branch_probe(false), "replica-sync-wasm"); + fn parse_request_rejects_malformed_json() { + let error = parse_request_model("{").expect_err("error"); + assert!(error.contains("EOF")); } }