//! Shared test utilities for battery tests. #![allow(clippy::expect_used)] // Test code uses expect() for clear failure messages // Re-export commonly used items for tests pub use ed25519_dalek::{Signer, SigningKey}; pub use rand::rngs::OsRng; pub use std::sync::Arc; pub use stemedb_core::serde::serialize; pub use stemedb_core::testing::AssertionBuilder; pub use stemedb_core::types::{ Assertion, EscalationLevel, EscalationPolicy, LifecycleStage, ObjectValue, ResolutionStatus, SignatureEntry, SourceClass, }; pub use stemedb_ingest::worker::{serialize_assertion, IngestWorker}; pub use stemedb_lens::{ AsyncLens, LayeredConsensusLens, RecencyLens, SyncLensWrapper, TrustAwareAuthorityLens, }; pub use stemedb_query::{ apply_source_class_decay, Materializer, Query, QueryEngine, SkepticResolver, }; pub use stemedb_storage::{ key_codec, EscalationStore, GenericEscalationStore, GenericIndexStore, GenericTrustRankStore, GenericVoteStore, HybridStore, IndexStore, KVStore, }; pub use stemedb_wal::Journal; pub use tempfile::tempdir; pub use tokio::sync::Mutex; /// Create a signed assertion with Ed25519 signature, source class, confidence, /// and arbitrary ObjectValue (text/bool, not just number). /// /// The signature signs the message `"{subject}:{predicate}"` which matches /// IngestWorker's verification logic. pub fn create_signed_assertion_with_source( subject: &str, predicate: &str, object: ObjectValue, source_class: SourceClass, confidence: f32, timestamp: u64, ) -> Assertion { let mut csprng = OsRng; let signing_key = SigningKey::generate(&mut csprng); let verifying_key = signing_key.verifying_key(); let message = format!("{}:{}", subject, predicate); let signature = signing_key.sign(message.as_bytes()); AssertionBuilder::new() .subject(subject) .predicate(predicate) .object(object) .source_class(source_class) .confidence(confidence) .lifecycle(LifecycleStage::Proposed) .timestamp(timestamp) .signatures(vec![SignatureEntry { agent_id: verifying_key.to_bytes(), signature: signature.to_bytes(), timestamp, }]) .build() } /// Store an assertion directly into H: and SP: keys (bypassing WAL/Ingest). /// /// Used for unit-style tests that don't need the full pipeline. pub async fn store_assertion_direct( store: &Arc, index_store: &GenericIndexStore>, assertion: &Assertion, ) { let bytes = serialize(assertion).expect("serialize assertion"); let hash = blake3::hash(&bytes); let hash_hex = hash.to_hex().to_string(); let key = key_codec::assertion_key(&assertion.subject, &hash_hex); store.put(&key, &bytes).await.expect("put assertion"); let assertion_hash: [u8; 32] = *hash.as_bytes(); index_store .add_to_indexes(&assertion.subject, &assertion.predicate, &assertion_hash) .await .expect("add to indexes"); }