rullst-orm 12.1.1

Fast, un-opinionated, database-agnostic ORM and query builder for Rust
Documentation
use serde_json::{Map, Value, json};

use super::{
    QdrantConfig, QdrantStore, VectorCollectionName, VectorDimensions, VectorPoint,
    VectorQueryLimit, VectorRepository,
};
use crate::polyglot::{Backend, Capability, PolyglotError};

fn payload(label: &str) -> Map<String, Value> {
    let Value::Object(payload) = json!({ "label": label }) else {
        unreachable!("object literal must remain an object");
    };
    payload
}

#[tokio::test]
async fn mock_runs_a_deterministic_cosine_lifecycle() {
    let store = QdrantStore::connect_or_mock(QdrantConfig::new("", ""))
        .expect("empty configuration should select the mock");
    assert!(store.is_mock());
    assert_eq!(QdrantStore::capabilities().backend(), Backend::Qdrant);
    assert!(
        QdrantStore::capabilities().supports(Capability::Vectors),
        "Qdrant should declare only its bounded vector capability"
    );
    let collection = VectorCollectionName::new("documents-v1").expect("valid collection");
    let dimensions = VectorDimensions::new(3).expect("valid dimensions");
    store
        .create_collection(&collection, dimensions)
        .await
        .expect("collection should be created");
    assert!(matches!(
        store.create_collection(&collection, dimensions).await,
        Err(PolyglotError::Conflict)
    ));

    store
        .upsert(
            &collection,
            VectorPoint::new(2, vec![0.0, 1.0, 0.0], payload("second")).expect("valid point"),
        )
        .await
        .expect("second point should be inserted");
    store
        .upsert(
            &collection,
            VectorPoint::new(1, vec![1.0, 0.0, 0.0], payload("closest")).expect("valid point"),
        )
        .await
        .expect("closest point should be inserted");

    let matches = store
        .search(
            &collection,
            &[0.9, 0.1, 0.0],
            VectorQueryLimit::new(2).expect("valid limit"),
        )
        .await
        .expect("search should succeed");
    assert_eq!(matches.len(), 2);
    assert_eq!(matches[0].id(), 1);
    assert_eq!(matches[0].payload()["label"], "closest");
    assert!(matches[0].score() > matches[1].score());

    store
        .delete(&collection, 1)
        .await
        .expect("delete should succeed");
    let matches = store
        .search(
            &collection,
            &[1.0, 0.0, 0.0],
            VectorQueryLimit::new(2).expect("valid limit"),
        )
        .await
        .expect("search after delete should succeed");
    assert_eq!(matches.len(), 1);
    assert_eq!(matches[0].id(), 2);
}

#[tokio::test]
async fn mock_rejects_dimension_mismatch() {
    let store = QdrantStore::connect_or_mock(QdrantConfig::new("mock://qdrant", "mock_key"))
        .expect("mock configuration should initialize");
    let collection = VectorCollectionName::new("documents").expect("valid collection");
    store
        .create_collection(
            &collection,
            VectorDimensions::new(3).expect("valid dimensions"),
        )
        .await
        .expect("collection should be created");
    let point = VectorPoint::new(1, vec![1.0, 0.0], Map::new()).expect("valid point");
    assert!(matches!(
        store.upsert(&collection, point).await,
        Err(PolyglotError::InvalidConfiguration {
            backend: "Qdrant",
            ..
        })
    ));
}

#[test]
fn validates_structural_and_resource_bounds() {
    assert!(VectorCollectionName::new("../escape").is_err());
    assert!(VectorCollectionName::new("-invalid").is_err());
    assert!(VectorDimensions::new(0).is_err());
    assert!(VectorQueryLimit::new(0).is_err());
    assert!(VectorQueryLimit::new(1_001).is_err());
    assert!(VectorPoint::new(1, Vec::new(), Map::new()).is_err());
    assert!(VectorPoint::new(1, vec![0.0, 0.0], Map::new()).is_err());
    assert!(VectorPoint::new(1, vec![f32::NAN], Map::new()).is_err());
    let mut oversized = Map::new();
    oversized.insert("content".to_owned(), Value::String("x".repeat(1024 * 1024)));
    assert!(VectorPoint::new(1, vec![1.0], oversized).is_err());
    assert!(
        QdrantConfig::new("mock_local", "mock_key")
            .with_response_limit(512)
            .is_err()
    );
}

#[test]
fn endpoint_policy_and_debug_output_are_fail_closed() {
    assert!(
        QdrantStore::connect_or_mock(QdrantConfig::new("http://qdrant.example.com", "secret"))
            .is_err()
    );
    assert!(
        QdrantStore::connect_or_mock(QdrantConfig::unauthenticated_local(
            "https://qdrant.example.com"
        ))
        .is_err()
    );
    assert!(
        QdrantStore::connect_or_mock(QdrantConfig::new(
            "https://qdrant.example.com/path",
            "secret"
        ))
        .is_err()
    );
    assert!(
        QdrantStore::connect_or_mock(QdrantConfig::new(
            "https://qdrant.example.com",
            "line\nbreak"
        ))
        .is_err()
    );
    let rendered = format!(
        "{:?}",
        QdrantConfig::new("https://private.example.com", "top-secret")
    );
    assert!(!rendered.contains("private.example.com"));
    assert!(!rendered.contains("top-secret"));
}