// Copyright (c) Microsoft. All rights reserved. using FluentAssertions; using Microsoft.Agents.AI.Workflows.Execution; namespace Microsoft.Agents.AI.Workflows.UnitTests; public class StateKeyObjectTests { [Fact] public void Test_ScopeId_Equality() { // The rules of ScopeId are simple: Private executor scopes (executorId, scopeId=null) are only equal to // themselves. Public ScopeIds are equal when their scopeNames are equal, regardless of executorId. ScopeId privateScope1 = new("executor1", null); ScopeId privateScope2 = new("executor2", null); Assert.NotEqual(privateScope1, privateScope2); Assert.Equal(privateScope1, new ScopeId("executor1", null)); ScopeId sharedScope1 = new("executor1", "sharedScope"); ScopeId sharedScope2 = new("executor2", "sharedScope"); Assert.Equal(sharedScope1, sharedScope2); Assert.NotEqual(sharedScope1, new ScopeId("executor1", "differentScope")); Assert.NotEqual(sharedScope1, privateScope1); } [Fact] public void Test_UpdateKey_Equality() { // The rules of UpdateKey are different from ScopeId. In the case of "shared scope", // two update keys with different ExecutorIds are not the same. const string Key1 = "key1"; const string Key2 = "key2"; UpdateKey privateScope1Key = new("executor1", null, Key1); UpdateKey privateScope1Key2 = new("executor1", null, Key2); Assert.NotEqual(privateScope1Key, privateScope1Key2); UpdateKey privateScope2Key = new("executor2", null, Key1); Assert.NotEqual(privateScope1Key, privateScope2Key); UpdateKey scope1Executor1Key = new("executor1", "sharedScope", Key1); UpdateKey scope1Executor2Key = new("executor2", "sharedScope", Key1); Assert.NotEqual(scope1Executor1Key, scope1Executor2Key); } [Fact] public void Test_UpdateKey_IsMatchingScope() { const string Key1 = "key1"; UpdateKey privateScope1Key = new("executor1", null, Key1); UpdateKey privateScope2Key = new("executor2", null, Key1); ScopeId privateScope1 = new("executor1", null); ScopeId privateScope2 = new("executor2", null); ValidateMatch(privateScope1Key, privateScope1, expectedStrict: true, expectedLoose: true); ValidateMatch(privateScope1Key, privateScope2, expectedStrict: false, expectedLoose: false); ValidateMatch(privateScope2Key, privateScope1, expectedStrict: false, expectedLoose: false); ValidateMatch(privateScope2Key, privateScope2, expectedStrict: true, expectedLoose: true); UpdateKey sharedScope1Key = new("executor1", "sharedScope", Key1); UpdateKey sharedScope2Key = new("executor2", "sharedScope", Key1); ScopeId sharedScope1 = new("executor1", "sharedScope"); ScopeId sharedScope2 = new("executor2", "sharedScope"); ValidateMatch(sharedScope1Key, sharedScope1, expectedStrict: true, expectedLoose: true); ValidateMatch(sharedScope1Key, sharedScope2, expectedStrict: false, expectedLoose: true); ValidateMatch(sharedScope2Key, sharedScope1, expectedStrict: false, expectedLoose: true); ValidateMatch(sharedScope2Key, sharedScope2, expectedStrict: true, expectedLoose: true); // Cross checks between private and shared scopes should never match ValidateMatch(privateScope1Key, sharedScope1, expectedStrict: false, expectedLoose: false); ValidateMatch(privateScope1Key, sharedScope2, expectedStrict: false, expectedLoose: false); ValidateMatch(privateScope2Key, sharedScope1, expectedStrict: false, expectedLoose: false); ValidateMatch(privateScope2Key, sharedScope2, expectedStrict: false, expectedLoose: false); ValidateMatch(sharedScope1Key, privateScope1, expectedStrict: false, expectedLoose: false); ValidateMatch(sharedScope1Key, privateScope2, expectedStrict: false, expectedLoose: false); ValidateMatch(sharedScope2Key, privateScope1, expectedStrict: false, expectedLoose: false); ValidateMatch(sharedScope2Key, privateScope2, expectedStrict: false, expectedLoose: false); static void ValidateMatch(UpdateKey key, ScopeId scope, bool expectedStrict, bool expectedLoose) { key.IsMatchingScope(scope, strict: true).Should().Be(expectedStrict); key.IsMatchingScope(scope, strict: false).Should().Be(expectedLoose); } } }