diff --git a/ArangoDB.Extensions.VectorData.Tests/ArangoDB.Extensions.VectorData.Tests.csproj b/ArangoDB.Extensions.VectorData.Tests/ArangoDB.Extensions.VectorData.Tests.csproj
new file mode 100644
index 00000000..a44e3b46
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/ArangoDB.Extensions.VectorData.Tests.csproj
@@ -0,0 +1,128 @@
+
+
+
+ net9.0
+ enable
+ enable
+ false
+ 733488cf-ebe1-45f3-8f3d-64056225edb6
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ArangoCollectionUnitTests.cs
+
+
+ ArangoCollectionUnitTests.cs
+
+
+ ArangoCollectionUnitTests.cs
+
+
+ ArangoCollectionUnitTests.cs
+
+
+ ArangoCollectionUnitTests.cs
+
+
+ ArangoCollectionUnitTests.cs
+
+
+ ArangoCollectionUnitTests.cs
+
+
+
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+ ArangoCollectionIntegrationTests.cs
+
+
+
+
+
+
+ ArangoCollectionIntegrationTests.GetAsyncWithFilter.cs
+
+
+ ArangoCollectionIntegrationTests.GetAsyncWithFilter.cs
+
+
+ ArangoCollectionIntegrationTests.GetAsyncWithFilter.cs
+
+
+ ArangoCollectionIntegrationTests.GetAsyncWithFilter.cs
+
+
+ ArangoCollectionIntegrationTests.GetAsyncWithFilter.cs
+
+
+
+
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.CollectionExistsAsync.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.CollectionExistsAsync.cs
new file mode 100644
index 00000000..cccc3e29
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.CollectionExistsAsync.cs
@@ -0,0 +1,41 @@
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+[TestFixture]
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task CollectionExistsAsync_ShouldReturnTrue_WhenCollectionExists()
+ {
+ // Arrange
+ string collectionName = Faker.Name.LastName();
+ await ArangoDbClient
+ .Collection
+ .PostCollectionAsync(new ()
+ {
+ Name = collectionName
+ });
+ using VectorStoreCollection collection = VectorStore
+ .GetCollection(collectionName, null);
+
+ // Act
+ bool exists = await collection.CollectionExistsAsync();
+
+ // Assert
+ exists.ShouldBeTrue();
+ }
+
+ [Test]
+ public async Task CollectionExistsAsync_ShouldReturnFalse_WhenCollectionDoesNotExist()
+ {
+ // Arrange
+ string randomCollectionName = Faker.Random.Word().ToLower();
+ VectorStoreCollection collection = VectorStore
+ .GetCollection(randomCollectionName, null);
+
+ // Act
+ bool exists = await collection.CollectionExistsAsync();
+
+ // Assert
+ exists.ShouldBeFalse();
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.DeleteAsync.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.DeleteAsync.cs
new file mode 100644
index 00000000..98c9c569
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.DeleteAsync.cs
@@ -0,0 +1,48 @@
+using ArangoDBNetStandard.DocumentApi.Models;
+
+using System.Net;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task DeleteAsync_ShouldDeleteDocument_WhenDocumentExists()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore
+ .GetCollection(CollectionName, null);
+ string key = Guid.NewGuid().ToString();
+ TestRecord record = new()
+ {
+ Key = key,
+ Name = Faker.Person.FullName
+ };
+ PostDocumentResponse postDocumentResponse = await ArangoDbClient
+ .Document
+ .PostDocumentAsync(collection.Name, record);
+
+ // Act
+ await collection.DeleteAsync(postDocumentResponse._key);
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ try
+ {
+ TestRecord testRecord = await ArangoDbClient
+ .Document
+ .GetDocumentAsync(
+ postDocumentResponse._id,
+ Arg.Any(),
+ Arg.Any());
+ }
+ catch (ApiErrorException ex)
+ {
+ ex.ShouldBeOfType();
+ ex.ApiError.Code.ShouldBe(HttpStatusCode.NotFound);
+ }
+ }
+ }
+
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.EnsureCollectionDeletedAsync.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.EnsureCollectionDeletedAsync.cs
new file mode 100644
index 00000000..863d131f
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.EnsureCollectionDeletedAsync.cs
@@ -0,0 +1,36 @@
+using ArangoDBNetStandard.CollectionApi.Models;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task EnsureCollectionDeletedAsync_ShouldDeleteCollection_WhenCollectionExists()
+ {
+ // Arrange
+ string collectionName = Faker.Random.String2(10);
+ await ArangoDbClient
+ .Collection
+ .PostCollectionAsync(new()
+ {
+ Name = collectionName,
+ Type = CollectionType.Document
+ });
+ VectorStoreCollection collection = VectorStore
+ .GetCollection(collectionName, null);
+
+ // Act & Assert
+ await Should.NotThrowAsync(() => collection.EnsureCollectionDeletedAsync());
+ }
+
+ [Test]
+ public async Task EnsureCollectionDeletedAsync_ShouldIgnoreException_WhenDocumentDoesNotExist()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore
+ .GetCollection(Faker.Random.String2(10), null);
+
+ // Act & Assert
+ await Should.NotThrowAsync(() => collection.EnsureCollectionDeletedAsync());
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.EnsureCollectionExistsAsync.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.EnsureCollectionExistsAsync.cs
new file mode 100644
index 00000000..6c5addfa
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.EnsureCollectionExistsAsync.cs
@@ -0,0 +1,47 @@
+using ArangoDBNetStandard.CollectionApi.Models;
+
+using System.Net;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task EnsureCollectionExistsAsync_ShouldCreateCollection_WhenDoesNotExist()
+ {
+ // Arrange
+ string collectionName = Faker.Random.String2(10);
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ collectionName,
+ null);
+
+ // Act
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ await Should.NotThrowAsync(()
+ => collection.EnsureCollectionExistsAsync());
+ GetCollectionResponse getCollectionResponse = await ArangoDbClient
+ .Collection
+ .GetCollectionAsync(collectionName);
+ getCollectionResponse.Name.ShouldBe(collectionName);
+ getCollectionResponse.Type.ShouldBe(CollectionType.Document);
+ getCollectionResponse.Code.ShouldBe(HttpStatusCode.OK);
+ }
+ }
+
+
+ [Test]
+ public async Task EnsureCollectionExistsAsync_ShouldIgnoreException_WhenAlreadyExists()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+
+ // Act & Assert
+ await Should.NotThrowAsync(()
+ => collection.EnsureCollectionExistsAsync());
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsync.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsync.cs
new file mode 100644
index 00000000..204d1e9e
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsync.cs
@@ -0,0 +1,56 @@
+using ArangoDBNetStandard.DocumentApi.Models;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task GetAysnc_ReturnsDocument_WhenDocumentExists()
+ {
+ // Arrange
+ string documentName = Faker.Random.Word();
+ TestRecord rec = new()
+ {
+ Name = documentName,
+ };
+ PostDocumentResponse newDoc = await ArangoDbClient
+ .Document
+ .PostDocumentAsync(CollectionName, rec);
+
+ using var collection = VectorStore.GetCollection(CollectionName, null);
+
+ // Act & Assert
+ using (Assert.EnterMultipleScope())
+ {
+ TestRecord? fetchedDoc = null;
+ await Should.NotThrowAsync(async () => fetchedDoc = await collection.GetAsync(newDoc._id));
+ fetchedDoc.ShouldNotBeNull();
+ fetchedDoc.Name.ShouldBe(documentName);
+ }
+ }
+
+ [Test]
+ public async Task GetAysnc_ReturnsNullWithoutThrowingException_WhenDocumentDoesNotExist()
+ {
+ // Arrange
+ string documentName = Faker.Name.LastName();
+ TestRecord rec = new()
+ {
+ Name = documentName,
+ };
+ string id=$"{CollectionName}/{Faker.Name.LastName()}";
+
+ using var collection = VectorStore.GetCollection(CollectionName, null);
+
+ // Act & Assert
+ using (Assert.EnterMultipleScope())
+ {
+ TestRecord? fetchedDoc = null;
+ await Should.NotThrowAsync(async () =>
+ {
+ fetchedDoc = await collection.GetAsync(id);
+ });
+ fetchedDoc.ShouldBeNull();
+ }
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.CollectionContainsMethods.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.CollectionContainsMethods.cs
new file mode 100644
index 00000000..c5dce386
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.CollectionContainsMethods.cs
@@ -0,0 +1,87 @@
+using System.Linq.Expressions;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithListContainsMethod()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ List names = ["TestWithListContains", "TestWithListContains2"];
+ Expression> filter = r => names.Contains(r.Name);
+ List expectedRecords =
+ [
+ new () { Name = "TestWithListContains" },
+ new () { Name = "TestWithListContains2" },
+ new () { Name = "NothingTestWithListNotContains" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("TestWithListContains");
+ results[1].Name.ShouldBe("TestWithListContains2");
+ }
+ }
+
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithIEnumerableContainsMethod()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ IEnumerable names = ["TestWithIEnumerableContains", "TestWithIEnumerableContains2"];
+ Expression> filter = r => names.Contains(r.Name);
+ List expectedRecords =
+ [
+ new () { Name = "TestWithIEnumerableContains" },
+ new () { Name = "TestWithIEnumerableContains2" },
+ new () { Name = "NothingTestWithIEnumerableContains" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("TestWithIEnumerableContains");
+ results[1].Name.ShouldBe("TestWithIEnumerableContains2");
+ }
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.EqualityOperator.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.EqualityOperator.cs
new file mode 100644
index 00000000..fe4f3765
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.EqualityOperator.cs
@@ -0,0 +1,78 @@
+using System.Linq.Expressions;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task GetAsyncWithFilterWithEqualityOperator_ShouldReturnExactlyOneRecord_WhenComapringWithEqualityOperator()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name == "TestEqualityOperator";
+ List expectedRecords =
+ [
+ new () { Name = "TestEqualityOperator" },
+ new () { Name = "TestEqualityOperator2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(1);
+ results.ShouldAllBe(r => r.Name != "Nothing");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnNoRecord_WhenComparingWithEqualityOperator()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name == "test";
+ List expectedRecords =
+ [
+ new () { Name = "Test" },
+ new () { Name = "Test2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ results.Count.ShouldBe(0);
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.EqualsMethods.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.EqualsMethods.cs
new file mode 100644
index 00000000..9da39648
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.EqualsMethods.cs
@@ -0,0 +1,82 @@
+using System.Linq.Expressions;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithEqualsMethod()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Equals("TestWithEqualsMethod");
+ List expectedRecords =
+ [
+ new () { Name = "TestWithEqualsMethod" },
+ new () { Name = "TestWithEqualsMethod2" },
+ new () { Name = "NothingTestWithEqualsMethod" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(1);
+ results[0].Name.ShouldBe("TestWithEqualsMethod");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithEqualsMethodWithStringComparison()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Equals("testWithEqualsmethodWithComparisonArg", StringComparison.OrdinalIgnoreCase);
+ List expectedRecords =
+ [
+ new () { Name = "TestWithEqualsMethodWithComparisonArg" },
+ new () { Name = "TestWithEqualsMethodWithComparisonArg2" },
+ new () { Name = "NothingTestWithEqualsMethodWithComparisonArg" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(1);
+ results[0].Name.ShouldBe("TestWithEqualsMethodWithComparisonArg");
+ }
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.LikeMethods.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.LikeMethods.cs
new file mode 100644
index 00000000..25697014
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.LikeMethods.cs
@@ -0,0 +1,162 @@
+using System.Linq.Expressions;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithLikeMethod()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => AqlFilters.Like(r.Name, "Test");
+ List expectedRecords =
+ [
+ new () { Name = "Test" },
+ new () { Name = "Test2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("Test");
+ results[1].Name.ShouldBe("Test2");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComapringWithExtensionMethod()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Like("Test");
+ List expectedRecords =
+ [
+ new () { Name = "Test" },
+ new () { Name = "Test2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("Test");
+ results[1].Name.ShouldBe("Test2");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComapringWithLikeMethodWithStringComparison()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => AqlFilters.Like(r.Name, "test", StringComparison.OrdinalIgnoreCase);
+ List expectedRecords =
+ [
+ new () { Name = "Test" },
+ new () { Name = "Test2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("Test");
+ results[1].Name.ShouldBe("Test2");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithLikeMethodWithStringComparison()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Like("test", StringComparison.OrdinalIgnoreCase);
+ List expectedRecords =
+ [
+ new () { Name = "Test" },
+ new () { Name = "Test2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("Test");
+ results[1].Name.ShouldBe("Test2");
+ }
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.StringContainsMethods.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.StringContainsMethods.cs
new file mode 100644
index 00000000..ab5c306e
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.StringContainsMethods.cs
@@ -0,0 +1,289 @@
+using System.Linq.Expressions;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithContainsMethod()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Contains("Test");
+ List expectedRecords =
+ [
+ new () { Name = "Test" },
+ new () { Name = "Test2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("Test");
+ results[1].Name.ShouldBe("Test2");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnNoRecord_WhenComparingWithContainsMethod()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Contains("test");
+ List expectedRecords =
+ [
+ new () { Name = "Test" },
+ new () { Name = "Test2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ results.Count.ShouldBe(0);
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithContainsMethodWithStringComparison()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Contains("test", StringComparison.OrdinalIgnoreCase);
+ List expectedRecords =
+ [
+ new () { Name = "Test" },
+ new () { Name = "Test2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("Test");
+ results[1].Name.ShouldBe("Test2");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnOneRecord_WhenComapringWithContainsMethodAndSkipProvided()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ FilteredRecordRetrievalOptions options = new()
+ {
+ Skip = 1
+ };
+ Expression> filter = r => r.Name.Contains("TestContainsWithSkip");
+ List expectedRecords =
+ [
+ new () { Name = "TestContainsWithSkip" },
+ new () { Name = "TestContainsWithSkip2" },
+ new () { Name = "TestUnknown" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2, options))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(1);
+ results[0].Name.ShouldBe("TestContainsWithSkip2");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithContainsMethodAndSortDefinitionProvided()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Contains("Test");
+
+ FilteredRecordRetrievalOptions options = new()
+ {
+ OrderBy = def => def.Descending(r => r.Name)
+ };
+ List expectedRecords =
+ [
+ new () { Name = "TestWithContainsMethodAndSortDefinitionProvided" },
+ new () { Name = "TestWithContainsMethodAndSortDefinitionProvided2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2, options))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("TestWithContainsMethodAndSortDefinitionProvided2");
+ results[1].Name.ShouldBe("TestWithContainsMethodAndSortDefinitionProvided");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnOneRecord_WhenFilterContainsSortDefinitionAndSkipProvided()
+ {
+ // Arrange
+
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ Expression> filter = r => r.Name.Contains("TestContainswithSortandSkip");
+
+ FilteredRecordRetrievalOptions options = new()
+ {
+ Skip = 1,
+ OrderBy = def => def.Descending(r => r.Name)
+ };
+ List expectedRecords =
+ [
+ new () { Name = "TestContainswithSortandSkip" },
+ new () { Name = "TestContainswithSortandSkip2" },
+ new () { Name = "Nothing" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2, options))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(1);
+ results[0].Name.ShouldBe("TestContainswithSortandSkip");
+ }
+ }
+
+ [Test]
+ public async Task GetAsyncWithFilter_ShouldReturnTwoRecords_WhenComparingWithContainsMethodWithParam()
+ {
+ // Arrange
+ VectorStoreCollection collection = VectorStore.GetCollection(
+ CollectionName,
+ null);
+ string filterText = "TestWithContainsMethodWithParam";
+ Expression> filter = r => r.Name.Contains(filterText);
+ List expectedRecords =
+ [
+ new () { Name = "TestWithContainsMethodWithParam" },
+ new () { Name = "TestWithContainsMethodWithParam2" },
+ new () { Name = "NothingWithNotContainsMethodWithParam" }
+ ];
+ await ArangoDbClient.Document
+ .PostDocumentsAsync(
+ CollectionName,
+ expectedRecords,
+ null,
+ null,
+ null,
+ default);
+
+ // Act
+ List results = [];
+ await foreach (TestRecord record in collection.GetAsync(filter, 2))
+ {
+ results.Add(record);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.Count.ShouldBe(2);
+ results[0].Name.ShouldBe("TestWithContainsMethodWithParam");
+ results[1].Name.ShouldBe("TestWithContainsMethodWithParam2");
+ }
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.cs
new file mode 100644
index 00000000..2ac410b7
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.GetAsyncWithFilter.cs
@@ -0,0 +1,5 @@
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+public partial class ArangoCollectionIntegrationTests
+{
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.cs
new file mode 100644
index 00000000..e3fe970d
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoCollectionIntegrationTests.cs
@@ -0,0 +1,15 @@
+using System.Text.Json.Serialization;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+[ExcludeFromCodeCoverage]
+public partial class ArangoCollectionIntegrationTests : ArangoDbIntegrationTestBase
+{
+ public class TestRecord
+ {
+ [JsonPropertyName("_key")]
+ public string Key { get; set; } = string.Empty;
+ public string Name { get; set; } = string.Empty;
+ public float[]? Embedding { get; set; }
+ }
+}
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoDbIntegrationTestBase.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoDbIntegrationTestBase.cs
new file mode 100644
index 00000000..72b3382d
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoDbIntegrationTestBase.cs
@@ -0,0 +1,118 @@
+using ArangoDBNetStandard.CollectionApi.Models;
+using ArangoDBNetStandard.Transport.Http;
+
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.AI;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+
+using OpenAI.Embeddings;
+
+using Testcontainers.ArangoDb;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+[ExcludeFromCodeCoverage]
+public abstract class ArangoDbIntegrationTestBase
+{
+ protected readonly IServiceCollection _services;
+ protected IEmbeddingGenerator> _embeddingGenerator;
+ protected HttpApiTransport _transport;
+ protected AsyncServiceScope _scope;
+ private readonly ArangoDbContainer _arangoDbContainer;
+
+ public ArangoDbIntegrationTestBase()
+ {
+ WebApplicationBuilder builder = WebApplication.CreateBuilder();
+ builder
+ .Configuration
+ .AddUserSecrets(true, true)
+ .AddEnvironmentVariables();
+ _services = builder.Services;
+ Faker = new Faker();
+ _arangoDbContainer = new ArangoDbBuilder()
+ .WithImage("arangodb:latest")
+ .WithPortBinding(8529, true)
+ .WithEnvironment("ARANGO_NO_AUTH", "1")
+ //.WithEnvironment("ARANGO_ROOT_PASSWORD", _rootPassword)
+ .Build();
+ }
+
+ public string Hostname => _arangoDbContainer.Hostname;
+ public int Port => _arangoDbContainer.GetMappedPublicPort();
+ public IArangoDBClient ArangoDbClient { get; private set; }
+ public string UserName { get; private set; }
+ public string DatabaseName { get; private set; }
+ public string CollectionName { get; private set; }
+ public Faker Faker { get; private set; }
+ public ServiceProvider ServiceProvider { get; private set; }
+ public IServiceProvider ScopedServiceProvider { get; private set; }
+ public VectorStore VectorStore { get; private set; }
+
+ [OneTimeSetUp]
+ public virtual async Task InitializeAsync()
+ {
+ await _arangoDbContainer.StartAsync();
+ DatabaseName = Faker.Random.String2(15);
+ CollectionName = Faker.Random.String2(15).ToLower();
+ ArangoDbClient = CreateArangoDbClient();
+ await ArangoDbClient.Database.PostDatabaseAsync(new()
+ {
+ Name = DatabaseName
+ });
+ await ArangoDbClient.Collection.PostCollectionAsync(new()
+ {
+ Name = CollectionName,
+ Type = CollectionType.Document,
+ WaitForSync = true,
+ });
+ _services.AddSingleton(ArangoDbClient);
+ _services.AddArangoVectorDatabase();
+ _services.AddScoped(sp =>
+ {
+ IConfiguration config = sp.GetRequiredService();
+ string? apiKey = config["OpenAIKey"];
+ if (string.IsNullOrEmpty(apiKey))
+ {
+ throw new InvalidOperationException("OpenAIKey configuration is missing.");
+ }
+
+ EmbeddingClient embeddingClient = new("text-embedding-3-small", apiKey);
+
+ // Adapt the EmbeddingClient to the IEmbeddingGenerator interface
+ IEmbeddingGenerator> generator = embeddingClient.AsIEmbeddingGenerator();
+ return generator;
+ });
+ ServiceProvider = _services.BuildServiceProvider();
+ _scope = ServiceProvider.CreateAsyncScope();
+ ScopedServiceProvider = _scope.ServiceProvider;
+ VectorStore = ScopedServiceProvider.GetRequiredService();
+ _embeddingGenerator = ScopedServiceProvider.GetRequiredService>>();
+ }
+
+ [OneTimeTearDown]
+ public virtual async Task DisposeAsync()
+ {
+ await ArangoDbClient.Database.DeleteDatabaseAsync(DatabaseName);
+ ArangoDbClient.Dispose();
+ VectorStore.Dispose();
+ _embeddingGenerator.Dispose();
+ await _scope.DisposeAsync();
+ await ServiceProvider.DisposeAsync();
+ _services.Clear();
+ await _arangoDbContainer.DisposeAsync();
+ }
+
+ private IArangoDBClient CreateArangoDbClient()
+ {
+ Uri baseUri = new($"http://{Hostname}:{Port}/");
+ _transport = HttpApiTransport.UsingBasicAuth(
+ baseUri,
+ "_system",
+ string.Empty);
+ IArangoDBClient client = new ArangoDBClient(_transport, true);
+ return client;
+ }
+}
+
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoHybridSearchableIntegrationTests.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoHybridSearchableIntegrationTests.cs
new file mode 100644
index 00000000..9eb44d87
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoHybridSearchableIntegrationTests.cs
@@ -0,0 +1,232 @@
+using Microsoft.Extensions.AI;
+
+using System.Text.Json.Serialization;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+[ExcludeFromCodeCoverage]
+public class ArangoHybridSearchableIntegrationTests : ArangoDbIntegrationTestBase
+{
+ [Test]
+ public async Task SearchAsync_WithoutSkippingData_CoversEmbeddingGenerationLogic()
+ {
+ // Arrange
+ try
+ {
+ // Insert test documents with vector embeddings
+ TestRecord[] testDocs = [
+ new() { Key = "doc1", Id = "doc1", Name = "Machine Learning", Description = "AI and ML concepts", },
+ new() { Key = "doc2", Id = "doc2", Name = "Data Science", Description = "Statistics and analysis", },
+ new() { Key = "doc3", Id = "doc3", Name = "Deep Learning", Description = "Neural networks", }
+ ];
+
+ List stringsToCreateEmbeddingFor = [
+ ..testDocs.Select(d => $"{d.Name}: {d.Description}")
+ ];
+ (string Value, Embedding Embedding)[] values = await _embeddingGenerator.GenerateAndZipAsync(stringsToCreateEmbeddingFor);
+
+ for (int i = 0; i < testDocs.Length; i++)
+ {
+ TestRecord doc = testDocs[i];
+ doc.Embedding = values[i].Embedding.Vector.Span.ToArray();
+ await ArangoDbClient.Document.PostDocumentAsync(CollectionName, doc);
+ }
+
+ VectorStoreCollectionDefinition definition = new();
+
+ ArangoHybridSearchable vectorSearchable = new(
+ CollectionName,
+ definition,
+ ServiceProvider);
+
+ HybridSearchOptions options = new()
+ {
+ IncludeVectors = true,
+ VectorProperty = e => e.Embedding,
+ AdditionalProperty = e => e.Description
+ };
+
+ // Act - This covers lines 68-82: embedding generation and vector processing
+ List> results = [];
+ await foreach (VectorSearchResult result in vectorSearchable.HybridSearchAsync(
+ "artificial intelligence",
+ ["AI"],
+ 10,
+ options))
+ {
+ results.Add(result);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.ShouldNotBeNull();
+ results.ShouldNotBeEmpty();
+ results.ForEach(result =>
+ {
+ result.Record.ShouldNotBeNull();
+ result.Score.ShouldNotBeNull();
+ result.Score.Value.ShouldBeGreaterThanOrEqualTo(0.0);
+ });
+ }
+ }
+ finally
+ {
+
+ }
+ }
+
+ [Test]
+ public async Task SearchAsync_WithSkippingData_CoversEmbeddingGenerationLogic()
+ {
+ // Arrange
+ try
+ {
+ // Insert test documents with vector embeddings
+ TestRecord[] testDocs = [
+ new() { Key = "doc1", Id = "doc1", Name = "Machine Learning", Description = "AI and ML concepts", },
+ new() { Key = "doc2", Id = "doc2", Name = "Data Science", Description = "Statistics and analysis", },
+ new() { Key = "doc3", Id = "doc3", Name = "Deep Learning", Description = "Neural networks", }
+ ];
+
+ List stringsToCreateEmbeddingFor = [
+ ..testDocs.Select(d => $"{d.Name}: {d.Description}")
+ ];
+ (string Value, Embedding Embedding)[] values = await _embeddingGenerator.GenerateAndZipAsync(stringsToCreateEmbeddingFor);
+
+ for (int i = 0; i < testDocs.Length; i++)
+ {
+ TestRecord doc = testDocs[i];
+ doc.Embedding = values[i].Embedding.Vector.Span.ToArray();
+ await ArangoDbClient.Document.PostDocumentAsync(CollectionName, doc);
+ }
+
+ VectorStoreCollectionDefinition definition = new();
+
+ ArangoHybridSearchable vectorSearchable = new(
+ CollectionName,
+ definition,
+ ServiceProvider);
+
+ HybridSearchOptions options = new()
+ {
+ IncludeVectors = true,
+ VectorProperty = e => e.Embedding,
+ AdditionalProperty = e => e.Description,
+ Skip = 1
+ };
+
+ // Act
+ List> results = [];
+ await foreach (VectorSearchResult result in vectorSearchable.HybridSearchAsync(
+ "artificial intelligence",
+ ["AI"],
+ 10,
+ options))
+ {
+ results.Add(result);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.ShouldNotBeNull();
+ results.ShouldNotBeEmpty();
+ results.ForEach(result =>
+ {
+ result.Record.ShouldNotBeNull();
+ result.Score.ShouldNotBeNull();
+ result.Score.Value.ShouldBeGreaterThanOrEqualTo(0.0);
+ });
+ }
+ }
+ finally
+ {
+
+ }
+ }
+
+ [Test]
+ public async Task SearchAsync_WithProjection_ReturnsProjectedColswithoutTheVectorProperty()
+ {
+ // Arrange
+ try
+ {
+ // Insert test documents with vector embeddings
+ TestRecord[] testDocs = [
+ new() { Key = "doc1", Id = "doc1", Name = "Machine Learning", Description = "AI and ML concepts", },
+ new() { Key = "doc2", Id = "doc2", Name = "Data Science", Description = "Statistics and analysis", },
+ new() { Key = "doc3", Id = "doc3", Name = "Deep Learning", Description = "Neural networks", }
+ ];
+
+ List stringsToCreateEmbeddingFor = [
+ ..testDocs.Select(d => $"{d.Name}: {d.Description}")
+ ];
+ (string Value, Embedding Embedding)[] values = await _embeddingGenerator.GenerateAndZipAsync(stringsToCreateEmbeddingFor);
+
+ for (int i = 0; i < testDocs.Length; i++)
+ {
+ TestRecord doc = testDocs[i];
+ doc.Embedding = values[i].Embedding.Vector.Span.ToArray();
+ await ArangoDbClient.Document.PostDocumentAsync(CollectionName, doc);
+ }
+
+ VectorStoreCollectionDefinition definition = new();
+
+ ArangoHybridSearchable vectorSearchable = new(
+ CollectionName,
+ definition,
+ ServiceProvider);
+
+ HybridSearchOptions options = new()
+ {
+ IncludeVectors = false,
+ VectorProperty = e => e.Embedding,
+ AdditionalProperty = e => e.Description,
+ Skip = 1
+ };
+
+ // Act - This covers lines 68-82: embedding generation and vector processing
+ List> results = [];
+ await foreach (VectorSearchResult result in vectorSearchable.HybridSearchAsync(
+ "artificial intelligence",
+ ["AI"],
+ 10,
+ options))
+ {
+ results.Add(result);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.ShouldNotBeNull();
+ results.ShouldNotBeEmpty();
+ results.ForEach(result =>
+ {
+ result.Record.ShouldNotBeNull();
+ result.Score.ShouldNotBeNull();
+ result.Score.Value.ShouldBeGreaterThanOrEqualTo(0.0);
+ });
+ }
+ }
+ finally
+ {
+
+ }
+ }
+ public class TestRecord
+ {
+ [JsonPropertyName("_key")]
+ public string Key { get; set; } = string.Empty;
+ [JsonPropertyName("id")]
+ public string Id { get; set; } = string.Empty;
+ [JsonPropertyName("name")]
+ public string Name { get; set; } = string.Empty;
+ [JsonPropertyName("description")]
+ public string Description { get; set; } = string.Empty;
+ [JsonPropertyName("embedding")]
+ public float[] Embedding { get; set; } = [];
+ }
+
+}
\ No newline at end of file
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoVectorSearchableIntegrationTests.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoVectorSearchableIntegrationTests.cs
new file mode 100644
index 00000000..264103b4
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoVectorSearchableIntegrationTests.cs
@@ -0,0 +1,226 @@
+using Microsoft.Extensions.AI;
+
+using System.Text.Json.Serialization;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+[ExcludeFromCodeCoverage]
+public class ArangoVectorSearchableIntegrationTests : ArangoDbIntegrationTestBase
+{
+ public class TestRecord
+ {
+ [JsonPropertyName("_key")]
+ public string Key { get; set; } = string.Empty;
+ [JsonPropertyName("id")]
+ public string Id { get; set; } = string.Empty;
+ [JsonPropertyName("name")]
+ public string Name { get; set; } = string.Empty;
+ [JsonPropertyName("description")]
+ public string Description { get; set; } = string.Empty;
+ [JsonPropertyName("embedding")]
+ public float[] Embedding { get; set; } = [];
+ }
+
+ [Test]
+ public async Task SearchAsync_WithoutSkippingData_CoversEmbeddingGenerationLogic()
+ {
+ // Arrange
+ try
+ {
+ // Insert test documents with vector embeddings
+ TestRecord[] testDocs = [
+ new() { Key = "doc1", Id = "doc1", Name = "Machine Learning", Description = "AI and ML concepts", },
+ new() { Key = "doc2", Id = "doc2", Name = "Data Science", Description = "Statistics and analysis", },
+ new() { Key = "doc3", Id = "doc3", Name = "Deep Learning", Description = "Neural networks", }
+ ];
+
+ List stringsToCreateEmbeddingFor = [
+ ..testDocs.Select(d => $"{d.Name}: {d.Description}")
+ ];
+ (string Value, Embedding Embedding)[] values = await _embeddingGenerator.GenerateAndZipAsync(stringsToCreateEmbeddingFor);
+
+ for (int i = 0; i < testDocs.Length; i++)
+ {
+ TestRecord doc = testDocs[i];
+ doc.Embedding = values[i].Embedding.Vector.Span.ToArray();
+ await ArangoDbClient.Document.PostDocumentAsync(CollectionName, doc);
+ }
+
+ VectorStoreCollectionDefinition definition = new();
+
+ ArangoVectorSearchable vectorSearchable = new(
+ CollectionName,
+ definition,
+ ServiceProvider);
+
+ VectorSearchOptions options = new()
+ {
+ IncludeVectors = true,
+ VectorProperty = e => e.Embedding
+ };
+
+ // Act - This covers lines 68-82: embedding generation and vector processing
+ List> results = [];
+ await foreach (VectorSearchResult result in vectorSearchable.SearchAsync(
+ "artificial intelligence",
+ 10,
+ options))
+ {
+ results.Add(result);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.ShouldNotBeNull();
+ results.ShouldNotBeEmpty();
+ results.ForEach(result =>
+ {
+ result.Record.ShouldNotBeNull();
+ result.Score.ShouldNotBeNull();
+ result.Score.Value.ShouldBeGreaterThanOrEqualTo(0.0);
+ });
+ }
+ }
+ finally
+ {
+
+ }
+ }
+
+ [Test]
+ public async Task SearchAsync_WithSkippingData_CoversEmbeddingGenerationLogic()
+ {
+ // Arrange
+ try
+ {
+ // Insert test documents with vector embeddings
+ TestRecord[] testDocs = [
+ new() { Key = "doc1", Id = "doc1", Name = "Machine Learning", Description = "AI and ML concepts", },
+ new() { Key = "doc2", Id = "doc2", Name = "Data Science", Description = "Statistics and analysis", },
+ new() { Key = "doc3", Id = "doc3", Name = "Deep Learning", Description = "Neural networks", }
+ ];
+
+ List stringsToCreateEmbeddingFor = [
+ ..testDocs.Select(d => $"{d.Name}: {d.Description}")
+ ];
+ (string Value, Embedding Embedding)[] values = await _embeddingGenerator.GenerateAndZipAsync(stringsToCreateEmbeddingFor);
+
+ for (int i = 0; i < testDocs.Length; i++)
+ {
+ TestRecord doc = testDocs[i];
+ doc.Embedding = values[i].Embedding.Vector.Span.ToArray();
+ await ArangoDbClient.Document.PostDocumentAsync(CollectionName, doc);
+ }
+
+ VectorStoreCollectionDefinition definition = new();
+
+ ArangoVectorSearchable vectorSearchable = new(
+ CollectionName,
+ definition,
+ ServiceProvider);
+
+ VectorSearchOptions options = new()
+ {
+ IncludeVectors = true,
+ VectorProperty = e => e.Embedding,
+ Skip = 1
+ };
+
+ // Act - This covers lines 68-82: embedding generation and vector processing
+ List> results = [];
+ await foreach (VectorSearchResult result in vectorSearchable.SearchAsync(
+ "artificial intelligence",
+ 10,
+ options))
+ {
+ results.Add(result);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.ShouldNotBeNull();
+ results.ShouldNotBeEmpty();
+ results.ForEach(result =>
+ {
+ result.Record.ShouldNotBeNull();
+ result.Score.ShouldNotBeNull();
+ result.Score.Value.ShouldBeGreaterThanOrEqualTo(0.0);
+ });
+ }
+ }
+ finally
+ {
+
+ }
+ }
+
+ [Test]
+ public async Task SearchAsync_WithProjection_ReturnsProjectedColswithoutTheVectorProperty()
+ {
+ // Arrange
+ try
+ {
+ // Insert test documents with vector embeddings
+ TestRecord[] testDocs = [
+ new() { Key = "doc1", Id = "doc1", Name = "Machine Learning", Description = "AI and ML concepts", },
+ new() { Key = "doc2", Id = "doc2", Name = "Data Science", Description = "Statistics and analysis", },
+ new() { Key = "doc3", Id = "doc3", Name = "Deep Learning", Description = "Neural networks", }
+ ];
+
+ List stringsToCreateEmbeddingFor = [
+ ..testDocs.Select(d => $"{d.Name}: {d.Description}")
+ ];
+ (string Value, Embedding Embedding)[] values = await _embeddingGenerator.GenerateAndZipAsync(stringsToCreateEmbeddingFor);
+
+ for (int i = 0; i < testDocs.Length; i++)
+ {
+ TestRecord doc = testDocs[i];
+ doc.Embedding = values[i].Embedding.Vector.Span.ToArray();
+ await ArangoDbClient.Document.PostDocumentAsync(CollectionName, doc);
+ }
+
+ VectorStoreCollectionDefinition definition = new();
+
+ ArangoVectorSearchable vectorSearchable = new(
+ CollectionName,
+ definition,
+ ServiceProvider);
+
+ VectorSearchOptions options = new()
+ {
+ IncludeVectors = false,
+ VectorProperty = e => e.Embedding,
+ Skip = 1
+ };
+
+ // Act - This covers lines 68-82: embedding generation and vector processing
+ List> results = [];
+ await foreach (VectorSearchResult result in vectorSearchable.SearchAsync(
+ "artificial intelligence",
+ 10,
+ options))
+ {
+ results.Add(result);
+ }
+
+ // Assert
+ using (Assert.EnterMultipleScope())
+ {
+ results.ShouldNotBeNull();
+ results.ShouldNotBeEmpty();
+ results.ForEach(result =>
+ {
+ result.Record.ShouldNotBeNull();
+ result.Score.ShouldNotBeNull();
+ result.Score.Value.ShouldBeGreaterThanOrEqualTo(0.0);
+ });
+ }
+ }
+ finally
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoVectorStoreIntegrationTests.cs b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoVectorStoreIntegrationTests.cs
new file mode 100644
index 00000000..0b54fd85
--- /dev/null
+++ b/ArangoDB.Extensions.VectorData.Tests/IntegrationTests/ArangoVectorStoreIntegrationTests.cs
@@ -0,0 +1,327 @@
+using ArangoDBNetStandard.CollectionApi.Models;
+using ArangoDBNetStandard.Transport.Http;
+
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+
+using System.Net;
+
+namespace ArangoDB.Extensions.VectorData.Tests.IntegrationTests;
+
+[ExcludeFromCodeCoverage]
+public class ArangoVectorStoreIntegrationTests : ArangoDbIntegrationTestBase
+{
+ // Your test methods go here
+ [Test]
+ public async Task GetCollection_ShouldReturnCollection_WhenCollectionExists()
+ {
+ // Act
+ using VectorStoreCollection> collectionToAssert = VectorStore
+ .GetCollection>(CollectionName, null);
+
+ // Assert
+ GetCollectionResponse getCollectionResponse = await ArangoDbClient.Collection
+ .GetCollectionAsync(CollectionName);
+
+ using (Assert.EnterMultipleScope())
+ {
+ collectionToAssert.ShouldNotBeNull();
+ collectionToAssert.Name.ShouldBe(getCollectionResponse.Name);
+ collectionToAssert.ShouldBeOfType>>();
+ getCollectionResponse.Code.ShouldBe(HttpStatusCode.OK);
+ getCollectionResponse.Error.ShouldBeFalse();
+ }
+ }
+
+ // Your test methods go here
+ [Test]
+ public async Task GetDyncamicCollection_ShouldReturnCollection_WhenCollectionExists()
+ {
+ // Arrange
+ VectorStore store = ScopedServiceProvider.GetRequiredService();
+
+ // Act
+ using VectorStoreCollection