use std::sync::Arc; use offline_web_model::Reference; use super::{ReferenceStore, SqliteReferenceStore, StoreError}; async fn create_test_store() -> SqliteReferenceStore { SqliteReferenceStore::new("sqlite::memory:").await.unwrap() } #[tokio::test] async fn test_store_and_retrieve_reference() { let store = create_test_store().await; // Create a test reference let reference = Reference::new( Some("test_content_address".to_string()), "test_reference".to_string(), ); // Store the reference store.store_reference(&reference).await.unwrap(); // Retrieve the reference by ID let retrieved = store.get_reference(&reference.id).await.unwrap(); // Verify the retrieved reference matches the original assert_eq!(retrieved.id, reference.id); assert_eq!(retrieved.content_address, reference.content_address); assert_eq!(retrieved.name, reference.name); assert_eq!(retrieved.dependents.len(), reference.dependents.len()); } #[tokio::test] async fn test_store_and_retrieve_content() { let store = create_test_store().await; let content = b"Hello, World!"; let content_address = "test_content_address"; // Store content store.store_content(content_address, content).await.unwrap(); // Create a reference pointing to this content let reference = Reference::new( Some(content_address.to_string()), "test_reference".to_string(), ); // Retrieve content using the reference let retrieved_content = store.get_content_for_reference(reference).await.unwrap(); // Verify the content matches assert_eq!(retrieved_content, String::from_utf8(content.to_vec()).unwrap()); } #[tokio::test] async fn test_reference_with_dependents() { let store = create_test_store().await; // Create a leaf reference (no dependents) let leaf_ref = Reference::new( Some("leaf_content_address".to_string()), "leaf_reference".to_string(), ); // Store the leaf reference store.store_reference(&leaf_ref).await.unwrap(); // Create a parent reference that depends on the leaf let parent_ref = Reference::new( Some("parent_content_address".to_string()), "parent_reference".to_string(), ).add_dep(Arc::new(leaf_ref.clone())); // Store the parent reference store.store_reference(&parent_ref).await.unwrap(); // Retrieve the parent reference let retrieved_parent = store.get_reference(&parent_ref.id).await.unwrap(); // Verify the parent has the correct dependent assert_eq!(retrieved_parent.dependents.len(), 1); assert_eq!(retrieved_parent.dependents[0].name, leaf_ref.name); } #[tokio::test] async fn test_get_graph() { let store = create_test_store().await; // Create a hierarchy of references let leaf1 = Reference::new( Some("leaf1_content".to_string()), "leaf1".to_string(), ); let leaf2 = Reference::new( Some("leaf2_content".to_string()), "leaf2".to_string(), ); let parent = Reference::new( Some("parent_content".to_string()), "parent".to_string(), ) .add_dep(Arc::new(leaf1.clone())) .add_dep(Arc::new(leaf2.clone())); let root = Reference::new( Some("root_content".to_string()), "root".to_string(), ).add_dep(Arc::new(parent.clone())); // Store all references store.store_reference(&leaf1).await.unwrap(); store.store_reference(&leaf2).await.unwrap(); store.store_reference(&parent).await.unwrap(); store.store_reference(&root).await.unwrap(); // Get the graph starting from root let graph = store.get_graph("root").await.unwrap(); // Verify we got all references in the graph assert_eq!(graph.len(), 4); // Verify we have all the expected references let names: Vec<_> = graph.iter().map(|r| &r.name).collect(); assert!(names.contains(&&"root".to_string())); assert!(names.contains(&&"parent".to_string())); assert!(names.contains(&&"leaf1".to_string())); assert!(names.contains(&&"leaf2".to_string())); } #[tokio::test] async fn test_nonexistent_reference() { let store = create_test_store().await; // Try to retrieve a reference that doesn't exist let result = store.get_reference("nonexistent_id").await; // Should return NoSuchReference error assert!(matches!(result, Err(StoreError::NoSuchReference))); } #[tokio::test] async fn test_nonexistent_content() { let store = create_test_store().await; // Create a reference with a content address that doesn't exist let reference = Reference::new( Some("nonexistent_content_address".to_string()), "test_reference".to_string(), ); // Try to retrieve content let result = store.get_content_for_reference(reference).await; // Should return NoSuchContentAddress error assert!(matches!(result, Err(StoreError::NoSuchContentAddress))); } #[tokio::test] async fn test_reference_without_content_address() { let store = create_test_store().await; // Create a reference without a content address let reference = Reference::new(None, "test_reference".to_string()); // Try to retrieve content let result = store.get_content_for_reference(reference).await; // Should return NoSuchContentAddress error assert!(matches!(result, Err(StoreError::NoSuchContentAddress))); } #[tokio::test] async fn test_schema_version_management() { let store = create_test_store().await; // Verify the schema version is correctly set let version = store.get_current_schema_version().await.unwrap(); assert_eq!(version, 1, "Schema version should be 1"); // Verify we can still perform basic operations let reference = Reference::new( Some("test_content".to_string()), "test_schema_version".to_string(), ); store.store_reference(&reference).await.unwrap(); let retrieved = store.get_reference(&reference.id).await.unwrap(); assert_eq!(retrieved.name, reference.name); }