// Copyright (c) Microsoft. All rights reserved. using System.Collections.Generic; using System.Text.Json; namespace Microsoft.Agents.AI.UnitTests; /// /// Unit tests for the class. /// public class ToolApprovalRuleTests { #region Construction and Defaults /// /// Verify that a new rule has the expected default values. /// [Fact] public void NewRule_HasDefaultValues() { // Act var rule = new ToolApprovalRule(); // Assert Assert.Equal(string.Empty, rule.ToolName); Assert.Null(rule.Arguments); } /// /// Verify that ToolName can be set. /// [Fact] public void ToolName_CanBeSet() { // Arrange & Act var rule = new ToolApprovalRule { ToolName = "ReadFile" }; // Assert Assert.Equal("ReadFile", rule.ToolName); } /// /// Verify that Arguments can be set. /// [Fact] public void Arguments_CanBeSet() { // Arrange & Act var args = new Dictionary { ["path"] = "test.txt" }; var rule = new ToolApprovalRule { ToolName = "ReadFile", Arguments = args }; // Assert Assert.NotNull(rule.Arguments); Assert.Equal("test.txt", rule.Arguments["path"]); } #endregion #region JSON Serialization /// /// Verify that a tool-level rule round-trips through JSON serialization. /// [Fact] public void Serialize_ToolLevelRule_RoundTrips() { // Arrange var rule = new ToolApprovalRule { ToolName = "MyTool" }; // Act var json = JsonSerializer.Serialize(rule, AgentJsonUtilities.DefaultOptions); var deserialized = JsonSerializer.Deserialize(json, AgentJsonUtilities.DefaultOptions); // Assert Assert.NotNull(deserialized); Assert.Equal("MyTool", deserialized!.ToolName); Assert.Null(deserialized.Arguments); } /// /// Verify that a tool+arguments rule round-trips through JSON serialization. /// [Fact] public void Serialize_ToolWithArgsRule_RoundTrips() { // Arrange var rule = new ToolApprovalRule { ToolName = "ReadFile", Arguments = new Dictionary { ["path"] = "test.txt", ["encoding"] = "utf-8" }, }; // Act var json = JsonSerializer.Serialize(rule, AgentJsonUtilities.DefaultOptions); var deserialized = JsonSerializer.Deserialize(json, AgentJsonUtilities.DefaultOptions); // Assert Assert.NotNull(deserialized); Assert.Equal("ReadFile", deserialized!.ToolName); Assert.NotNull(deserialized.Arguments); Assert.Equal(2, deserialized.Arguments!.Count); Assert.Equal("test.txt", deserialized.Arguments["path"]); Assert.Equal("utf-8", deserialized.Arguments["encoding"]); } /// /// Verify that JSON property names are correctly applied. /// [Fact] public void Serialize_UsesJsonPropertyNames() { // Arrange var rule = new ToolApprovalRule { ToolName = "MyTool", Arguments = new Dictionary { ["key"] = "value" }, }; // Act var json = JsonSerializer.Serialize(rule, AgentJsonUtilities.DefaultOptions); // Assert Assert.Contains("\"toolName\"", json); Assert.Contains("\"arguments\"", json); } /// /// Verify that a list of rules round-trips through JSON serialization. /// [Fact] public void Serialize_RuleList_RoundTrips() { // Arrange var rules = new List { new() { ToolName = "ToolA" }, new() { ToolName = "ToolB", Arguments = new Dictionary { ["x"] = "1" } }, }; // Act var json = JsonSerializer.Serialize(rules, AgentJsonUtilities.DefaultOptions); var deserialized = JsonSerializer.Deserialize>(json, AgentJsonUtilities.DefaultOptions); // Assert Assert.NotNull(deserialized); Assert.Equal(2, deserialized!.Count); Assert.Equal("ToolA", deserialized[0].ToolName); Assert.Null(deserialized[0].Arguments); Assert.Equal("ToolB", deserialized[1].ToolName); Assert.NotNull(deserialized[1].Arguments); } #endregion }