// Copyright (c) Microsoft. All rights reserved. using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel.Connectors.MongoDB; using MongoDB.Driver; using VectorData.ConformanceTests; using Xunit; namespace MongoDB.ConformanceTests; public class MongoDependencyInjectionTests : DependencyInjectionTests.Record>, string, DependencyInjectionTests.Record> { protected const string ConnectionString = "mongodb://localhost:27017"; protected const string DatabaseName = "dbName"; protected override void PopulateConfiguration(ConfigurationManager configuration, object? serviceKey = null) => configuration.AddInMemoryCollection( [ new(CreateConfigKey("Mongo", serviceKey, "ConnectionString"), ConnectionString), new(CreateConfigKey("Mongo", serviceKey, "DatabaseName"), DatabaseName), ]); private static string ConnectionStringProvider(IServiceProvider sp) => sp.GetRequiredService().GetRequiredSection("Mongo:ConnectionString").Value!; private static string ConnectionStringProvider(IServiceProvider sp, object serviceKey) => sp.GetRequiredService().GetRequiredSection(CreateConfigKey("Mongo", serviceKey, "ConnectionString")).Value!; private static string DatabaseNameProvider(IServiceProvider sp) => sp.GetRequiredService().GetRequiredSection("Mongo:DatabaseName").Value!; private static string DatabaseNameProvider(IServiceProvider sp, object serviceKey) => sp.GetRequiredService().GetRequiredSection(CreateConfigKey("Mongo", serviceKey, "DatabaseName")).Value!; public override IEnumerable> CollectionDelegates { get { yield return (services, serviceKey, name, lifetime) => serviceKey is null ? services .AddSingleton(sp => new MongoClient(MongoClientSettings.FromConnectionString(ConnectionString))) .AddSingleton(sp => sp.GetRequiredService().GetDatabase(DatabaseName)) .AddMongoCollection(name, lifetime: lifetime) : services .AddSingleton(sp => new MongoClient(MongoClientSettings.FromConnectionString(ConnectionString))) .AddSingleton(sp => sp.GetRequiredService().GetDatabase(DatabaseName)) .AddKeyedMongoCollection(serviceKey, name, lifetime: lifetime); yield return (services, serviceKey, name, lifetime) => serviceKey is null ? services.AddMongoCollection( name, ConnectionString, DatabaseName, lifetime: lifetime) : services.AddKeyedMongoCollection( serviceKey, name, ConnectionString, DatabaseName, lifetime: lifetime); yield return (services, serviceKey, name, lifetime) => serviceKey is null ? services.AddMongoCollection( name, ConnectionStringProvider, DatabaseNameProvider, lifetime: lifetime) : services.AddKeyedMongoCollection( serviceKey, name, sp => ConnectionStringProvider(sp, serviceKey), sp => DatabaseNameProvider(sp, serviceKey), lifetime: lifetime); } } public override IEnumerable> StoreDelegates { get { yield return (services, serviceKey, lifetime) => serviceKey is null ? services.AddMongoVectorStore( ConnectionString, DatabaseName, lifetime: lifetime) : services.AddKeyedMongoVectorStore( serviceKey, ConnectionString, DatabaseName, lifetime: lifetime); yield return (services, serviceKey, lifetime) => serviceKey is null ? services .AddSingleton(sp => new MongoClient(MongoClientSettings.FromConnectionString(ConnectionString))) .AddSingleton(sp => sp.GetRequiredService().GetDatabase(DatabaseName)) .AddMongoVectorStore(lifetime: lifetime) : services .AddSingleton(sp => new MongoClient(MongoClientSettings.FromConnectionString(ConnectionString))) .AddSingleton(sp => sp.GetRequiredService().GetDatabase(DatabaseName)) .AddKeyedMongoVectorStore(serviceKey, lifetime: lifetime); } } [Fact] public void ConnectionStringProviderCantBeNull() { IServiceCollection services = new ServiceCollection(); Assert.Throws(() => services.AddMongoCollection( name: "notNull", connectionStringProvider: null!, databaseNameProvider: DatabaseNameProvider)); Assert.Throws(() => services.AddKeyedMongoCollection( serviceKey: "notNull", name: "notNull", connectionStringProvider: null!, databaseNameProvider: DatabaseNameProvider)); } [Fact] public void DatabaseNameProviderCantBeNull() { IServiceCollection services = new ServiceCollection(); Assert.Throws(() => services.AddMongoCollection( name: "notNull", connectionStringProvider: ConnectionStringProvider, databaseNameProvider: null!)); Assert.Throws(() => services.AddKeyedMongoCollection( serviceKey: "notNull", name: "notNull", connectionStringProvider: ConnectionStringProvider, databaseNameProvider: null!)); } [Fact] public void ConnectionStringCantBeNullOrEmpty() { IServiceCollection services = new ServiceCollection(); Assert.Throws(() => services.AddMongoVectorStore(connectionString: null!, DatabaseName)); Assert.Throws(() => services.AddKeyedMongoVectorStore(serviceKey: "notNull", connectionString: null!, DatabaseName)); Assert.Throws(() => services.AddMongoCollection( name: "notNull", connectionString: null!, DatabaseName)); Assert.Throws(() => services.AddMongoCollection( name: "notNull", connectionString: "", DatabaseName)); Assert.Throws(() => services.AddKeyedMongoCollection( serviceKey: "notNull", name: "notNull", connectionString: null!, DatabaseName)); Assert.Throws(() => services.AddKeyedMongoCollection( serviceKey: "notNull", name: "notNull", connectionString: "", DatabaseName)); } [Fact] public void DatabaseNameCantBeNullOrEmpty() { IServiceCollection services = new ServiceCollection(); Assert.Throws(() => services.AddMongoVectorStore(ConnectionString, databaseName: null!)); Assert.Throws(() => services.AddKeyedMongoVectorStore(serviceKey: "notNull", ConnectionString, databaseName: null!)); Assert.Throws(() => services.AddMongoCollection( name: "notNull", ConnectionString, databaseName: null!)); Assert.Throws(() => services.AddMongoCollection( name: "notNull", ConnectionString, databaseName: "")); Assert.Throws(() => services.AddKeyedMongoCollection( serviceKey: "notNull", name: "notNull", ConnectionString, databaseName: null!)); Assert.Throws(() => services.AddKeyedMongoCollection( serviceKey: "notNull", name: "notNull", ConnectionString, databaseName: "")); } }