diff --git a/CHANGELOG.md b/CHANGELOG.md index 945a538..756c3ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Refactor: deduplicated test database setup across common/src/storage/ types by routing remaining inline SurrealDbClient::memory() calls through shared setup_test_db(), prepare_text_chunk_test_db(), and prepare_knowledge_entity_test_db() helpers; removed redundant apply_migrations() calls after setup_test_db() and collapsed configure_embedding_dimension + redefine_hnsw_index triplication into prepare_*_test_db helpers - Refactor: split knowledge-graph.js monolith into focused functions (loadGraphData, buildSvg, createSimulation, drawLinks/Nodes/Labels, createHighlighting, createZoom, attachResize); fixed dead duplicate zoom instance - Refactor: extracted rubberbanding scroll logic in design-polish.js into standalone attachRubberbanding helper; removed dead pullDistance state diff --git a/common/src/storage/db.rs b/common/src/storage/db.rs index 5245ebd..b810236 100644 --- a/common/src/storage/db.rs +++ b/common/src/storage/db.rs @@ -313,8 +313,7 @@ mod tests { use crate::stored_object; use anyhow::{self, Context}; - use super::*; - use uuid::Uuid; + use crate::test_utils::setup_test_db; stored_object!(Dummy, "dummy", { name: String @@ -322,15 +321,7 @@ mod tests { #[tokio::test] async fn test_initialization_and_crud() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to initialize schema".to_string())?; + let db = setup_test_db().await?; let dummy = Dummy { id: "abc".to_string(), @@ -374,15 +365,7 @@ mod tests { #[tokio::test] async fn upsert_item_overwrites_existing_records() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to initialize schema".to_string())?; + let db = setup_test_db().await?; let mut dummy = Dummy { id: "abc".to_string(), @@ -431,12 +414,7 @@ mod tests { #[tokio::test] async fn test_applying_migrations() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - + let db = setup_test_db().await?; db.apply_migrations() .await .with_context(|| "Failed to build indexes".to_string())?; diff --git a/common/src/storage/types/analytics.rs b/common/src/storage/types/analytics.rs index 8e76457..18ea82b 100644 --- a/common/src/storage/types/analytics.rs +++ b/common/src/storage/types/analytics.rs @@ -108,6 +108,7 @@ mod tests { #![allow(clippy::expect_used, clippy::must_use_candidate)] use super::*; use crate::stored_object; + use crate::test_utils::setup_test_db; use anyhow::{self}; use uuid::Uuid; @@ -120,10 +121,7 @@ mod tests { #[tokio::test] async fn test_analytics_initialization() -> anyhow::Result<()> { // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; // Test initialization of analytics let analytics = Analytics::ensure_initialized(&db).await?; @@ -145,10 +143,7 @@ mod tests { #[tokio::test] async fn test_get_current_analytics() -> anyhow::Result<()> { // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; // Initialize analytics Analytics::ensure_initialized(&db).await?; @@ -165,10 +160,7 @@ mod tests { #[tokio::test] async fn test_increment_visitors() -> anyhow::Result<()> { // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; // Initialize analytics Analytics::ensure_initialized(&db).await?; @@ -190,10 +182,7 @@ mod tests { #[tokio::test] async fn test_increment_page_loads() -> anyhow::Result<()> { // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; // Initialize analytics Analytics::ensure_initialized(&db).await?; @@ -214,11 +203,7 @@ mod tests { #[tokio::test] async fn test_get_users_amount() -> anyhow::Result<()> { - // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()).await?; // Test with no users let count = Analytics::get_users_amount(&db).await?; assert_eq!(count, 0); @@ -246,10 +231,7 @@ mod tests { #[tokio::test] async fn test_increment_visitors_without_prior_init() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; let analytics = Analytics::increment_visitors(&db).await?; assert_eq!(analytics.visitors, 1); assert_eq!(analytics.page_loads, 0); @@ -259,10 +241,7 @@ mod tests { #[tokio::test] async fn test_increment_page_loads_without_prior_init() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; let analytics = Analytics::increment_page_loads(&db).await?; assert_eq!(analytics.page_loads, 1); assert_eq!(analytics.visitors, 0); @@ -272,10 +251,7 @@ mod tests { #[tokio::test] async fn test_visitor_and_page_load_increments_are_independent() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; let after_visitors = Analytics::increment_visitors(&db).await?; assert_eq!(after_visitors.visitors, 1); assert_eq!(after_visitors.page_loads, 0); @@ -293,10 +269,7 @@ mod tests { #[tokio::test] async fn test_record_page_view() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; let first_view = Analytics::record_page_view(&db, true).await?; assert_eq!(first_view.visitors, 1); assert_eq!(first_view.page_loads, 1); @@ -310,11 +283,7 @@ mod tests { #[tokio::test] async fn test_get_current_nonexistent() -> anyhow::Result<()> { - // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()).await?; // Don't initialize analytics and try to get it let result = Analytics::get_current(&db).await; diff --git a/common/src/storage/types/conversation.rs b/common/src/storage/types/conversation.rs index f13dbee..945b49c 100644 --- a/common/src/storage/types/conversation.rs +++ b/common/src/storage/types/conversation.rs @@ -157,6 +157,7 @@ impl Conversation { mod tests { #![allow(clippy::expect_used, clippy::must_use_candidate)] use crate::storage::types::message::MessageRole; + use crate::test_utils::setup_test_db; use anyhow::{self, Context}; use super::*; @@ -181,11 +182,7 @@ mod tests { #[tokio::test] async fn test_create_conversation() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; let user_id = "test_user"; let title = "Test Conversation"; @@ -214,11 +211,7 @@ mod tests { #[tokio::test] async fn test_get_complete_conversation_not_found() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; let result = Conversation::get_complete_conversation("nonexistent_id", "test_user", &db).await; @@ -234,11 +227,7 @@ mod tests { #[tokio::test] async fn test_get_complete_conversation_unauthorized() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; let user_id_1 = "user_1"; let conversation = @@ -264,11 +253,7 @@ mod tests { #[tokio::test] async fn test_patch_title_success() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; let user_id = "user_1"; let original_title = "Original Title"; @@ -297,11 +282,7 @@ mod tests { #[tokio::test] async fn test_patch_title_not_found() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; let result = Conversation::patch_title("nonexistent", "user_x", "New Title", &db).await; @@ -316,11 +297,7 @@ mod tests { #[tokio::test] async fn test_patch_title_unauthorized() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; let owner_id = "owner"; let other_user_id = "intruder"; @@ -345,11 +322,7 @@ mod tests { #[tokio::test] async fn test_get_user_sidebar_conversations_filters_and_orders_by_updated_at_desc() { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .expect("Failed to start in-memory surrealdb"); + let db = setup_test_db().await.expect("setup_test_db"); let user_id = "sidebar_user"; let other_user_id = "other_user"; @@ -398,11 +371,7 @@ mod tests { #[tokio::test] async fn test_sidebar_projection_reflects_patch_title_and_updated_at_reorder() { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .expect("Failed to start in-memory surrealdb"); + let db = setup_test_db().await.expect("setup_test_db"); let user_id = "sidebar_patch_user"; let base = Utc::now(); @@ -440,11 +409,7 @@ mod tests { #[tokio::test] async fn test_get_complete_conversation_with_messages() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; let user_id_1 = "user_1"; let conversation = Conversation::new(user_id_1.to_string(), "Conversation".to_string()); @@ -527,11 +492,7 @@ mod tests { #[tokio::test] async fn test_sidebar_conversation_deserializes_id_from_db_record() { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .expect("Failed to start in-memory surrealdb"); + let db = setup_test_db().await.expect("setup_test_db"); let owner = "sidebar_owner"; let conversation = Conversation::new(owner.to_string(), "Sidebar title".to_string()); @@ -551,9 +512,7 @@ mod tests { #[tokio::test] async fn test_message_query_filters_by_owner_user_id_in_sql() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; + let db = setup_test_db().await?; let owner = "owner_user"; let intruder = "intruder_user"; @@ -590,9 +549,7 @@ mod tests { #[tokio::test] async fn test_get_complete_conversation_orders_messages_by_updated_at() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; + let db = setup_test_db().await?; let user_id = "order_user"; let conversation = Conversation::new(user_id.to_string(), "Ordered".to_string()); @@ -637,9 +594,7 @@ mod tests { #[tokio::test] async fn test_patch_title_not_found_when_conversation_deleted() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; + let db = setup_test_db().await?; let owner = "owner"; let conversation = Conversation::new(owner.to_string(), "To delete".to_string()); diff --git a/common/src/storage/types/file_info.rs b/common/src/storage/types/file_info.rs index 24e450f..287b0ee 100644 --- a/common/src/storage/types/file_info.rs +++ b/common/src/storage/types/file_info.rs @@ -327,6 +327,7 @@ mod tests { use super::*; use crate::storage::store::testing::TestStorageManager; + use crate::test_utils::setup_test_db; use axum::http::HeaderMap; use axum_typed_multipart::FieldMetadata; use std::{io::Write, path::Path}; @@ -378,15 +379,7 @@ mod tests { #[tokio::test] async fn test_fileinfo_create_read_delete_with_storage_manager() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - + let db = setup_test_db().await?; let content = b"This is a test file for StorageManager operations"; let file_name = "storage_manager_test.txt"; let field_data = create_test_file(content, file_name)?; @@ -435,15 +428,7 @@ mod tests { #[tokio::test] async fn test_fileinfo_preserves_original_filename_and_sanitizes_path() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - + let db = setup_test_db().await?; let content = b"filename sanitization"; let original_name = "Complex name (1).txt"; let expected_sanitized = "Complex_name__1_.txt"; @@ -470,15 +455,7 @@ mod tests { #[tokio::test] async fn test_fileinfo_duplicate_detection_with_storage_manager() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - + let db = setup_test_db().await?; let content = b"This is a test file for StorageManager duplicate detection"; let file_name = "storage_manager_duplicate.txt"; let field_data = create_test_file(content, file_name)?; @@ -538,15 +515,7 @@ mod tests { #[tokio::test] async fn test_file_creation() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; - + let db = setup_test_db().await?; let content = b"This is a test file content"; let file_name = "test_file.txt"; let field_data = create_test_file(content, file_name)?; @@ -585,15 +554,7 @@ mod tests { #[tokio::test] async fn test_file_duplicate_detection() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; - + let db = setup_test_db().await?; // First, store a file with known content let content = b"This is a test file for duplicate detection"; let file_name = "original.txt"; @@ -692,12 +653,7 @@ mod tests { #[tokio::test] async fn test_get_by_sha_not_found() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - + let db = setup_test_db().await?; let result = FileInfo::get_by_sha("nonexistent_sha_hash", "user123", &db).await; assert!(result.is_err()); @@ -710,12 +666,7 @@ mod tests { #[tokio::test] async fn test_get_by_sha_resists_query_injection() { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .expect("Failed to start in-memory surrealdb"); - + let db = setup_test_db().await.expect("setup test db"); let now = Utc::now(); let file_info = FileInfo { id: Uuid::new_v4().to_string(), @@ -740,15 +691,7 @@ mod tests { #[tokio::test] async fn test_duplicate_detection_is_per_user() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - + let db = setup_test_db().await?; let content = b"shared content across users"; let test_storage = TestStorageManager::new_memory() .await @@ -783,10 +726,7 @@ mod tests { #[tokio::test] async fn test_get_by_sha_not_found_for_other_user() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - + let db = setup_test_db().await?; let now = Utc::now(); let sha = "abc123sha"; let owner = "owner_user"; @@ -816,9 +756,7 @@ mod tests { #[tokio::test] async fn test_new_with_storage_missing_file_name() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; + let db = setup_test_db().await?; let test_storage = TestStorageManager::new_memory().await?; let field_data = create_test_file_without_name(b"data")?; @@ -832,9 +770,7 @@ mod tests { #[tokio::test] async fn test_new_with_storage_empty_file() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; + let db = setup_test_db().await?; let test_storage = TestStorageManager::new_memory().await?; let file_info = FileInfo::new_with_storage( @@ -856,10 +792,7 @@ mod tests { #[tokio::test] async fn test_duplicate_upload_persists_single_row_per_user_sha() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database).await?; - db.apply_migrations().await?; + let db = setup_test_db().await?; let test_storage = TestStorageManager::new_memory().await?; let storage = test_storage.storage(); let user_id = "dedup_user"; @@ -901,12 +834,7 @@ mod tests { #[tokio::test] async fn test_manual_file_info_creation() { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .expect("Failed to start in-memory surrealdb"); - + let db = setup_test_db().await.expect("setup test db"); // Create a FileInfo instance directly let now = Utc::now(); let file_info = FileInfo { @@ -939,15 +867,7 @@ mod tests { #[tokio::test] async fn test_delete_by_id() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; - + let db = setup_test_db().await?; // Create and persist a test file via FileInfo::new_with_storage let user_id = "user123"; let test_storage = TestStorageManager::new_memory() @@ -985,12 +905,7 @@ mod tests { #[tokio::test] async fn test_delete_by_id_not_found() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - + let db = setup_test_db().await?; // Try to delete a file that doesn't exist let test_storage = TestStorageManager::new_memory() .await @@ -1006,12 +921,7 @@ mod tests { #[tokio::test] async fn test_get_by_id() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - + let db = setup_test_db().await?; // Create a FileInfo instance directly let now = Utc::now(); let file_id = Uuid::new_v4().to_string(); @@ -1045,12 +955,7 @@ mod tests { #[tokio::test] async fn test_get_by_id_not_found() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - + let db = setup_test_db().await?; // Try to retrieve a non-existent ID let non_existent_id = "non-existent-file-id"; let result = FileInfo::get_by_id(non_existent_id, &db).await; diff --git a/common/src/storage/types/ingestion_task.rs b/common/src/storage/types/ingestion_task.rs index 58abdbc..62788c6 100644 --- a/common/src/storage/types/ingestion_task.rs +++ b/common/src/storage/types/ingestion_task.rs @@ -630,6 +630,7 @@ mod tests { use super::*; use crate::storage::types::ingestion_payload::IngestionPayload; + use crate::test_utils::setup_test_db; fn create_payload(user_id: &str) -> IngestionPayload { IngestionPayload::Text { @@ -641,11 +642,7 @@ mod tests { } async fn memory_db() -> anyhow::Result { - let namespace = "test_ns"; - let database = Uuid::new_v4().to_string(); - SurrealDbClient::memory(namespace, &database) - .await - .with_context(|| "in-memory surrealdb".to_string()) + setup_test_db().await } #[tokio::test] diff --git a/common/src/storage/types/knowledge_entity.rs b/common/src/storage/types/knowledge_entity.rs index d72b212..3b46000 100644 --- a/common/src/storage/types/knowledge_entity.rs +++ b/common/src/storage/types/knowledge_entity.rs @@ -496,9 +496,8 @@ mod tests { use super::*; use crate::storage::indexes::rebuild; use crate::storage::types::knowledge_entity_embedding::KnowledgeEntityEmbedding; - use crate::test_utils::configure_embedding_dimension; + use crate::test_utils::{prepare_knowledge_entity_test_db, setup_test_db}; use anyhow::{self, Context}; - use uuid::Uuid; #[test] fn embedding_input_text_uses_canonical_type_label() { @@ -617,19 +616,7 @@ mod tests { #[tokio::test] async fn test_delete_by_source_id() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; - - configure_embedding_dimension(&db, 5).await?; - KnowledgeEntityEmbedding::redefine_hnsw_index(&db, 5) - .await - .with_context(|| "Failed to redefine index length".to_string())?; + let db = prepare_knowledge_entity_test_db(5).await?; let source_id = "source123".to_string(); let entity_type = KnowledgeEntityType::Document; @@ -725,21 +712,9 @@ mod tests { #[tokio::test] async fn test_delete_by_source_id_resists_query_injection() { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) + let db = prepare_knowledge_entity_test_db(3) .await - .expect("Failed to start in-memory surrealdb"); - db.apply_migrations() - .await - .expect("Failed to apply migrations"); - - configure_embedding_dimension(&db, 3) - .await - .expect("configure dim"); - KnowledgeEntityEmbedding::redefine_hnsw_index(&db, 3) - .await - .expect("Failed to redefine index length"); + .expect("prepare test db"); let user_id = "user123".to_string(); @@ -791,18 +766,9 @@ mod tests { #[tokio::test] async fn test_vector_search_returns_empty_when_no_embeddings() { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) + let db = prepare_knowledge_entity_test_db(3) .await - .expect("Failed to start in-memory surrealdb"); - db.apply_migrations() - .await - .expect("Failed to apply migrations"); - - KnowledgeEntityEmbedding::redefine_hnsw_index(&db, 3) - .await - .expect("Failed to redefine index length"); + .expect("prepare test db"); let results = KnowledgeEntity::vector_search(5, &[0.1, 0.2, 0.3], &db, "user") .await @@ -812,19 +778,7 @@ mod tests { #[tokio::test] async fn test_vector_search_single_result() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; - - configure_embedding_dimension(&db, 3).await?; - KnowledgeEntityEmbedding::redefine_hnsw_index(&db, 3) - .await - .with_context(|| "Failed to redefine index length".to_string())?; + let db = prepare_knowledge_entity_test_db(3).await?; let user_id = "user".to_string(); let source_id = "src".to_string(); @@ -880,19 +834,7 @@ mod tests { #[tokio::test] async fn test_vector_search_orders_by_similarity() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; - - configure_embedding_dimension(&db, 3).await?; - KnowledgeEntityEmbedding::redefine_hnsw_index(&db, 3) - .await - .with_context(|| "Failed to redefine index length".to_string())?; + let db = prepare_knowledge_entity_test_db(3).await?; let user_id = "user".to_string(); let e1 = KnowledgeEntity::new( @@ -979,19 +921,7 @@ mod tests { #[tokio::test] async fn test_vector_search_with_orphaned_embedding() -> anyhow::Result<()> { - let namespace = "test_ns_orphan"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; - - configure_embedding_dimension(&db, 3).await?; - KnowledgeEntityEmbedding::redefine_hnsw_index(&db, 3) - .await - .with_context(|| "Failed to redefine index length".to_string())?; + let db = prepare_knowledge_entity_test_db(3).await?; let user_id = "user".to_string(); let source_id = "src".to_string(); @@ -1031,14 +961,7 @@ mod tests { #[tokio::test] async fn test_fts_search_returns_empty_when_no_entities() -> anyhow::Result<()> { - let namespace = "fts_entity_ns_empty"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; + let db = setup_test_db().await?; ensure_entity_fts_indexes(&db).await?; rebuild(&db) .await @@ -1054,14 +977,7 @@ mod tests { #[tokio::test] async fn test_fts_search_single_result() -> anyhow::Result<()> { - let namespace = "fts_entity_ns_single"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; + let db = setup_test_db().await?; ensure_entity_fts_indexes(&db).await?; let user_id = "fts_user"; @@ -1093,14 +1009,7 @@ mod tests { #[tokio::test] async fn test_fts_search_orders_by_score_and_filters_user() -> anyhow::Result<()> { - let namespace = "fts_entity_ns_order"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; + let db = setup_test_db().await?; ensure_entity_fts_indexes(&db).await?; let user_id = "fts_user_order"; diff --git a/common/src/storage/types/message.rs b/common/src/storage/types/message.rs index 4a0f073..2e6bb76 100644 --- a/common/src/storage/types/message.rs +++ b/common/src/storage/types/message.rs @@ -78,7 +78,7 @@ pub fn format_history(history: &[Message]) -> String { mod tests { #![allow(clippy::expect_used, clippy::must_use_candidate)] use super::*; - use crate::storage::db::SurrealDbClient; + use crate::test_utils::setup_test_db; use anyhow::{self, Context}; #[tokio::test] @@ -106,11 +106,7 @@ mod tests { #[tokio::test] async fn test_message_persistence() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &uuid::Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; let conversation_id = "test_conversation"; let message = Message::new( diff --git a/common/src/storage/types/scratchpad.rs b/common/src/storage/types/scratchpad.rs index 5de11b9..2dc3df7 100644 --- a/common/src/storage/types/scratchpad.rs +++ b/common/src/storage/types/scratchpad.rs @@ -221,19 +221,11 @@ mod tests { use anyhow::{self, Context}; use super::*; + use crate::test_utils::setup_test_db; #[tokio::test] async fn test_create_scratchpad() -> anyhow::Result<()> { - // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; // Create a new scratchpad let user_id = "test_user"; @@ -271,15 +263,7 @@ mod tests { #[tokio::test] async fn test_get_by_user() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let user_id = "test_user"; @@ -333,15 +317,7 @@ mod tests { #[tokio::test] async fn test_archive_and_restore() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let user_id = "test_user"; let scratchpad = Scratchpad::new(user_id.to_string(), "Test".to_string()); @@ -368,15 +344,7 @@ mod tests { #[tokio::test] async fn test_update_content() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let user_id = "test_user"; let scratchpad = Scratchpad::new(user_id.to_string(), "Test".to_string()); @@ -398,15 +366,7 @@ mod tests { #[tokio::test] async fn test_update_content_unauthorized() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let owner_id = "owner"; let other_user = "other_user"; @@ -428,15 +388,7 @@ mod tests { #[tokio::test] async fn test_delete_scratchpad() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let user_id = "test_user"; let scratchpad = Scratchpad::new(user_id.to_string(), "Test".to_string()); @@ -461,15 +413,7 @@ mod tests { #[tokio::test] async fn test_delete_unauthorized() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let owner_id = "owner"; let other_user = "other_user"; @@ -498,13 +442,7 @@ mod tests { #[tokio::test] async fn test_timezone_aware_scratchpad_conversion() -> anyhow::Result<()> { - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to create test database".to_string())?; - - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let user_id = "test_user_123"; let scratchpad = diff --git a/common/src/storage/types/system_settings.rs b/common/src/storage/types/system_settings.rs index 215da0e..d2e504d 100644 --- a/common/src/storage/types/system_settings.rs +++ b/common/src/storage/types/system_settings.rs @@ -334,6 +334,7 @@ mod tests { use anyhow::{self, Context}; use super::*; + use crate::test_utils::setup_test_db; use uuid::Uuid; async fn get_hnsw_index_dimension( @@ -417,17 +418,7 @@ mod tests { #[tokio::test] async fn test_settings_initialization() -> anyhow::Result<()> { - // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - // Test initialization of system settings - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let settings = SystemSettings::get_current(&db) .await .with_context(|| "Failed to get system settings".to_string())?; @@ -464,19 +455,8 @@ mod tests { #[tokio::test] async fn test_get_current_settings() -> anyhow::Result<()> { - // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; + let db = setup_test_db().await?; - // Initialize settings - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; - - // Test get_current method let settings = SystemSettings::get_current(&db) .await .with_context(|| "Failed to get current settings".to_string())?; @@ -489,17 +469,7 @@ mod tests { #[tokio::test] async fn test_update_settings() -> anyhow::Result<()> { - // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - - // Initialize settings - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; // Create updated settings let mut updated_settings = SystemSettings::get_current(&db) @@ -532,13 +502,7 @@ mod tests { #[tokio::test] async fn test_get_current_nonexistent() -> anyhow::Result<()> { - // Setup in-memory database for testing - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - + let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()).await?; // Don't initialize settings and try to get them let result = SystemSettings::get_current(&db).await; @@ -555,12 +519,7 @@ mod tests { #[tokio::test] async fn test_update_rejects_zero_embedding_dimensions() -> anyhow::Result<()> { - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let mut invalid_settings = SystemSettings::get_current(&db) .await @@ -574,12 +533,7 @@ mod tests { #[tokio::test] async fn test_patch_updates_without_cloning_full_settings() -> anyhow::Result<()> { - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let updated = SystemSettingsPatch { registrations_enabled: Some(false), @@ -595,12 +549,7 @@ mod tests { #[tokio::test] async fn test_patch_leaves_unmentioned_fields_unchanged() -> anyhow::Result<()> { - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let original = SystemSettings::get_current(&db) .await @@ -630,12 +579,7 @@ mod tests { #[tokio::test] async fn test_update_rejects_empty_model_name() -> anyhow::Result<()> { - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let mut invalid_settings = SystemSettings::get_current(&db) .await @@ -649,12 +593,7 @@ mod tests { #[tokio::test] async fn test_update_normalizes_record_id() -> anyhow::Result<()> { - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let mut settings = SystemSettings::get_current(&db) .await @@ -672,12 +611,7 @@ mod tests { async fn test_update_preserves_embedding_backend() -> anyhow::Result<()> { use crate::utils::embedding::EmbeddingProvider; - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let provider = EmbeddingProvider::new_hashed(384) .with_context(|| "Failed to create hashed embedding provider".to_string())?; @@ -704,12 +638,7 @@ mod tests { async fn test_sync_from_embedding_provider_updates_mismatched_settings() -> anyhow::Result<()> { use crate::utils::embedding::EmbeddingProvider; - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let provider = EmbeddingProvider::new_hashed(384) .with_context(|| "Failed to create hashed embedding provider".to_string())?; @@ -733,12 +662,7 @@ mod tests { async fn test_sync_from_embedding_provider_is_noop_when_already_synced() -> anyhow::Result<()> { use crate::utils::embedding::EmbeddingProvider; - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let provider = EmbeddingProvider::new_hashed(384) .with_context(|| "Failed to create hashed embedding provider".to_string())?; @@ -757,12 +681,7 @@ mod tests { async fn test_sync_rejects_provider_dimension_above_u32_max() -> anyhow::Result<()> { use crate::utils::embedding::EmbeddingProvider; - let db = SurrealDbClient::memory("test_ns", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "Failed to apply migrations".to_string())?; + let db = setup_test_db().await?; let provider = EmbeddingProvider::new_hashed((u32::MAX as usize) + 1) .with_context(|| "Failed to create oversized hashed provider".to_string())?; @@ -773,14 +692,7 @@ mod tests { #[tokio::test] async fn test_migration_after_changing_embedding_length() -> anyhow::Result<()> { - let db = SurrealDbClient::memory("test", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start DB".to_string())?; - - // Apply initial migrations. This sets up the text_chunk index with DIMENSION 1536. - db.apply_migrations() - .await - .with_context(|| "Initial migration failed".to_string())?; + let db = setup_test_db().await?; let initial_chunk = TextChunk::new( "source1".into(), @@ -811,14 +723,7 @@ mod tests { ) -> anyhow::Result<()> { use crate::utils::embedding::EmbeddingProvider; - let db = SurrealDbClient::memory("test", &Uuid::new_v4().to_string()) - .await - .with_context(|| "Failed to start DB".to_string())?; - - // Apply initial migrations. This sets up the text_chunk index with DIMENSION 1536. - db.apply_migrations() - .await - .with_context(|| "Initial migration failed".to_string())?; + let db = setup_test_db().await?; let mut current_settings = SystemSettings::get_current(&db) .await @@ -902,12 +807,7 @@ mod tests { #[tokio::test] async fn index_rebuild_lease_is_exclusive_on_system_settings() -> anyhow::Result<()> { - let namespace = "system_settings_index_rebuild"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .context("in-memory db")?; - db.apply_migrations().await.context("migrations")?; + let db = setup_test_db().await?; assert!( SystemSettings::try_acquire_index_rebuild_lease(&db, "worker-a").await?, diff --git a/common/src/storage/types/text_chunk.rs b/common/src/storage/types/text_chunk.rs index b632489..025e98b 100644 --- a/common/src/storage/types/text_chunk.rs +++ b/common/src/storage/types/text_chunk.rs @@ -322,9 +322,10 @@ mod tests { use super::*; use crate::storage::indexes::{ensure_runtime, rebuild}; use crate::storage::types::text_chunk_embedding::TextChunkEmbedding; - use crate::test_utils::configure_embedding_dimension; + use crate::test_utils::{ + configure_embedding_dimension, prepare_text_chunk_test_db, setup_test_db, + }; use surrealdb::RecordId; - use uuid::Uuid; async fn ensure_chunk_fts_index(db: &SurrealDbClient) -> anyhow::Result<()> { let snowball_sql = r#" @@ -363,21 +364,9 @@ mod tests { #[tokio::test] async fn test_delete_by_source_id() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - + let db = prepare_text_chunk_test_db(5).await?; let source_id = "source123".to_string(); let user_id = "user123".to_string(); - configure_embedding_dimension(&db, 5).await?; - TextChunkEmbedding::redefine_hnsw_index(&db, 5) - .await - .with_context(|| "redefine index".to_string())?; let chunk1 = TextChunk::new( source_id.clone(), @@ -446,18 +435,7 @@ mod tests { #[tokio::test] async fn test_delete_by_nonexistent_source_id() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - configure_embedding_dimension(&db, 5).await?; - TextChunkEmbedding::redefine_hnsw_index(&db, 5) - .await - .with_context(|| "redefine index".to_string())?; + let db = prepare_text_chunk_test_db(5).await?; let real_source_id = "real_source".to_string(); let chunk = TextChunk::new( @@ -490,18 +468,9 @@ mod tests { #[tokio::test] async fn test_delete_by_source_id_resists_query_injection() { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) + let db = prepare_text_chunk_test_db(5) .await - .expect("Failed to start in-memory surrealdb"); - db.apply_migrations().await.expect("migrations"); - configure_embedding_dimension(&db, 5) - .await - .expect("configure dim"); - TextChunkEmbedding::redefine_hnsw_index(&db, 5) - .await - .expect("redefine index"); + .expect("prepare test db"); let chunk1 = TextChunk::new( "safe_source".to_string(), @@ -544,24 +513,11 @@ mod tests { #[tokio::test] async fn test_store_with_embedding_creates_both_records() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - + let db = prepare_text_chunk_test_db(3).await?; let source_id = "store-src".to_string(); let user_id = "user_store".to_string(); let chunk = TextChunk::new(source_id.clone(), "chunk body".to_string(), user_id.clone()); - configure_embedding_dimension(&db, 3).await?; - TextChunkEmbedding::redefine_hnsw_index(&db, 3) - .await - .with_context(|| "redefine index".to_string())?; - TextChunk::store_with_embedding(chunk.clone(), vec![0.1, 0.2, 0.3], 3, &db) .await .with_context(|| "store with embedding".to_string())?; @@ -588,14 +544,7 @@ mod tests { #[tokio::test] async fn test_store_with_embedding_with_runtime_indexes() -> anyhow::Result<()> { - let namespace = "test_ns_runtime"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; + let db = setup_test_db().await?; let embedding_dimension = 3usize; configure_embedding_dimension( @@ -639,19 +588,7 @@ mod tests { #[tokio::test] async fn test_vector_search_returns_empty_when_no_embeddings() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - - configure_embedding_dimension(&db, 3).await?; - TextChunkEmbedding::redefine_hnsw_index(&db, 3) - .await - .with_context(|| "redefine index".to_string())?; + let db = prepare_text_chunk_test_db(3).await?; let results: Vec = TextChunk::vector_search(5, &[0.1, 0.2, 0.3], &db, "user") @@ -663,19 +600,7 @@ mod tests { #[tokio::test] async fn test_vector_search_single_result() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - - configure_embedding_dimension(&db, 3).await?; - TextChunkEmbedding::redefine_hnsw_index(&db, 3) - .await - .with_context(|| "redefine index".to_string())?; + let db = prepare_text_chunk_test_db(3).await?; let source_id = "src".to_string(); let user_id = "user".to_string(); @@ -704,19 +629,7 @@ mod tests { #[tokio::test] async fn test_vector_search_orders_by_similarity() -> anyhow::Result<()> { - let namespace = "test_ns"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - - configure_embedding_dimension(&db, 3).await?; - TextChunkEmbedding::redefine_hnsw_index(&db, 3) - .await - .with_context(|| "redefine index".to_string())?; + let db = prepare_text_chunk_test_db(3).await?; let user_id = "user".to_string(); let chunk1 = TextChunk::new("s1".to_string(), "chunk one".to_string(), user_id.clone()); @@ -745,14 +658,7 @@ mod tests { #[tokio::test] async fn test_fts_search_returns_empty_when_no_chunks() -> anyhow::Result<()> { - let namespace = "fts_chunk_ns_empty"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; + let db = setup_test_db().await?; ensure_chunk_fts_index(&db).await?; rebuild(&db) .await @@ -768,14 +674,7 @@ mod tests { #[tokio::test] async fn test_fts_search_single_result() -> anyhow::Result<()> { - let namespace = "fts_chunk_ns_single"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; + let db = setup_test_db().await?; ensure_chunk_fts_index(&db).await?; let user_id = "fts_user"; @@ -804,14 +703,7 @@ mod tests { #[tokio::test] async fn test_fts_search_orders_by_score_and_filters_user() -> anyhow::Result<()> { - let namespace = "fts_chunk_ns_order"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; + let db = setup_test_db().await?; ensure_chunk_fts_index(&db).await?; let user_id = "fts_user_order"; @@ -866,14 +758,7 @@ mod tests { #[tokio::test] async fn test_store_with_embedding_rejects_wrong_dimension() -> anyhow::Result<()> { - let namespace = "test_ns_dim"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; + let db = setup_test_db().await?; configure_embedding_dimension(&db, 3).await?; let chunk = TextChunk::new("src".to_string(), "body".to_string(), "user".to_string()); @@ -888,18 +773,7 @@ mod tests { #[tokio::test] async fn test_vector_search_with_orphaned_embedding() -> anyhow::Result<()> { - let namespace = "test_ns_orphan_chunk"; - let database = &Uuid::new_v4().to_string(); - let db = SurrealDbClient::memory(namespace, database) - .await - .with_context(|| "Failed to start in-memory surrealdb".to_string())?; - db.apply_migrations() - .await - .with_context(|| "migrations".to_string())?; - configure_embedding_dimension(&db, 3).await?; - TextChunkEmbedding::redefine_hnsw_index(&db, 3) - .await - .with_context(|| "redefine index".to_string())?; + let db = prepare_text_chunk_test_db(3).await?; let user_id = "user".to_string(); let chunk = TextChunk::new(