// Copyright (c) Microsoft. All rights reserved. using System; namespace Microsoft.Agents.AI.FoundryMemory.UnitTests; /// /// Tests for constructor validation. /// /// /// Since directly uses , /// integration tests are used to verify the memory operations. These unit tests focus on: /// - Constructor parameter validation /// - State initializer validation /// public sealed class FoundryMemoryProviderTests { [Fact] public void Constructor_Throws_WhenClientIsNull() { // Act & Assert ArgumentNullException ex = Assert.Throws(() => new FoundryMemoryProvider( null!, "store", stateInitializer: _ => new(new FoundryMemoryProviderScope("test")))); Assert.Equal("client", ex.ParamName); } [Fact] public void Constructor_Throws_WhenStateInitializerIsNull() { // Arrange using TestableAIProjectClient testClient = new(); // Act & Assert ArgumentNullException ex = Assert.Throws(() => new FoundryMemoryProvider( testClient.Client, "store", stateInitializer: null!)); Assert.Equal("stateInitializer", ex.ParamName); } [Fact] public void Constructor_Throws_WhenMemoryStoreNameIsEmpty() { // Arrange using TestableAIProjectClient testClient = new(); // Act & Assert ArgumentException ex = Assert.Throws(() => new FoundryMemoryProvider( testClient.Client, "", stateInitializer: _ => new(new FoundryMemoryProviderScope("test")))); Assert.Equal("memoryStoreName", ex.ParamName); } [Fact] public void Constructor_Throws_WhenMemoryStoreNameIsNull() { // Arrange using TestableAIProjectClient testClient = new(); // Act & Assert ArgumentNullException ex = Assert.Throws(() => new FoundryMemoryProvider( testClient.Client, null!, stateInitializer: _ => new(new FoundryMemoryProviderScope("test")))); Assert.Equal("memoryStoreName", ex.ParamName); } [Fact] public void Scope_Throws_WhenScopeIsNull() { // Act & Assert Assert.Throws(() => new FoundryMemoryProviderScope(null!)); } [Fact] public void Scope_Throws_WhenScopeIsEmpty() { // Act & Assert Assert.Throws(() => new FoundryMemoryProviderScope("")); } [Fact] public void StateInitializer_Throws_WhenScopeIsNull() { // Arrange using TestableAIProjectClient testClient = new(); FoundryMemoryProvider sut = new( testClient.Client, "store", stateInitializer: _ => new(null!)); // Act & Assert - state initializer validation is deferred to first use Assert.Throws(() => { // Force state initialization by creating a session-like scenario // The validation happens inside the ValidateStateInitializer wrapper try { // The stateInitializer wraps with validation, so calling it will throw var field = typeof(FoundryMemoryProvider).GetField("_sessionState", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var sessionState = field!.GetValue(sut); var method = sessionState!.GetType().GetMethod("GetOrInitializeState"); method!.Invoke(sessionState, [null]); } catch (System.Reflection.TargetInvocationException tie) when (tie.InnerException is not null) { throw tie.InnerException; } }); } [Fact] public void Constructor_Succeeds_WithValidParameters() { // Arrange using TestableAIProjectClient testClient = new(); // Act FoundryMemoryProvider sut = new( testClient.Client, "my-store", stateInitializer: _ => new(new FoundryMemoryProviderScope("user-456"))); // Assert Assert.NotNull(sut); } }