| File: Model\GenAISchemaHelpersTests.cs | Web Access |
| Project: src\tests\Aspire.Dashboard.Tests\Aspire.Dashboard.Tests.csproj (Aspire.Dashboard.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json.Nodes; using Aspire.Dashboard.Model.GenAI; using Microsoft.OpenApi; using Xunit; namespace Aspire.Dashboard.Tests.Model; public sealed class GenAISchemaHelpersTests { [Fact] public void ConvertTypeToNames_HandlesVariousTypeCombinations() { // Test single types var stringSchema = new OpenApiSchema { Type = JsonSchemaType.String }; var typeNames = GenAISchemaHelpers.ConvertTypeToNames(stringSchema); Assert.Single(typeNames); Assert.Equal("string", typeNames[0]); // Test multiple types (nullable string) - null should be excluded from display var nullableStringSchema = new OpenApiSchema { Type = JsonSchemaType.String | JsonSchemaType.Null }; typeNames = GenAISchemaHelpers.ConvertTypeToNames(nullableStringSchema); Assert.Single(typeNames); Assert.Equal("string", typeNames[0]); // Test array with items var arraySchema = new OpenApiSchema { Type = JsonSchemaType.Array, Items = new OpenApiSchema { Type = JsonSchemaType.String } }; typeNames = GenAISchemaHelpers.ConvertTypeToNames(arraySchema); Assert.Single(typeNames); Assert.Equal("array<string>", typeNames[0]); // Test nullable array with items - null should be excluded var nullableArraySchema = new OpenApiSchema { Type = JsonSchemaType.Array | JsonSchemaType.Null, Items = new OpenApiSchema { Type = JsonSchemaType.Number } }; typeNames = GenAISchemaHelpers.ConvertTypeToNames(nullableArraySchema); Assert.Single(typeNames); Assert.Equal("array<number>", typeNames[0]); // Test array without items var arrayNoItemsSchema = new OpenApiSchema { Type = JsonSchemaType.Array }; typeNames = GenAISchemaHelpers.ConvertTypeToNames(arrayNoItemsSchema); Assert.Single(typeNames); Assert.Equal("array", typeNames[0]); // Test null schema - should return empty list typeNames = GenAISchemaHelpers.ConvertTypeToNames(null); Assert.Empty(typeNames); // Test schema with no type - should return empty list var noTypeSchema = new OpenApiSchema(); typeNames = GenAISchemaHelpers.ConvertTypeToNames(noTypeSchema); Assert.Empty(typeNames); // Test schema with only null type - should return "null" since type is only null var onlyNullSchema = new OpenApiSchema { Type = JsonSchemaType.Null }; typeNames = GenAISchemaHelpers.ConvertTypeToNames(onlyNullSchema); Assert.Single(typeNames); Assert.Equal("null", typeNames[0]); // Test multiple types without null var multiTypeSchema = new OpenApiSchema { Type = JsonSchemaType.String | JsonSchemaType.Number }; typeNames = GenAISchemaHelpers.ConvertTypeToNames(multiTypeSchema); Assert.Equal(2, typeNames.Count); Assert.Contains("number", typeNames); Assert.Contains("string", typeNames); } [Fact] public void TryConvertToJsonSchemaType_ValidTypes_ReturnsTrue() { Assert.True(GenAISchemaHelpers.TryConvertToJsonSchemaType("null", out var nullType)); Assert.Equal(JsonSchemaType.Null, nullType); Assert.True(GenAISchemaHelpers.TryConvertToJsonSchemaType("boolean", out var boolType)); Assert.Equal(JsonSchemaType.Boolean, boolType); Assert.True(GenAISchemaHelpers.TryConvertToJsonSchemaType("integer", out var intType)); Assert.Equal(JsonSchemaType.Integer, intType); Assert.True(GenAISchemaHelpers.TryConvertToJsonSchemaType("number", out var numberType)); Assert.Equal(JsonSchemaType.Number, numberType); Assert.True(GenAISchemaHelpers.TryConvertToJsonSchemaType("string", out var stringType)); Assert.Equal(JsonSchemaType.String, stringType); Assert.True(GenAISchemaHelpers.TryConvertToJsonSchemaType("object", out var objectType)); Assert.Equal(JsonSchemaType.Object, objectType); Assert.True(GenAISchemaHelpers.TryConvertToJsonSchemaType("array", out var arrayType)); Assert.Equal(JsonSchemaType.Array, arrayType); } [Fact] public void TryConvertToJsonSchemaType_InvalidType_ReturnsFalse() { Assert.False(GenAISchemaHelpers.TryConvertToJsonSchemaType("invalid", out _)); Assert.False(GenAISchemaHelpers.TryConvertToJsonSchemaType(null, out _)); Assert.False(GenAISchemaHelpers.TryConvertToJsonSchemaType("", out _)); } [Fact] public void ParseTypeValue_HandlesUnexpectedJsonObject_ReturnsNull() { // Test that when "type" field is a JsonObject instead of a string, it returns null instead of throwing var typeAsObject = JsonNode.Parse("""{"description": "This is an object instead of a string"}"""); var result = GenAISchemaHelpers.ParseTypeValue(typeAsObject); Assert.Null(result); } [Fact] public void ParseTypeValue_HandlesArrayWithNonStringItems_SkipsInvalidItems() { // Test that when "type" array contains non-string items (e.g., objects), it skips them gracefully var typeArrayWithObjects = JsonNode.Parse("""["string", {"invalid": "object"}, "number"]""") as JsonArray; var result = GenAISchemaHelpers.ParseTypeValue(typeArrayWithObjects); // Should have parsed "string" and "number" but skipped the object Assert.NotNull(result); Assert.True(result!.Value.HasFlag(JsonSchemaType.String)); Assert.True(result.Value.HasFlag(JsonSchemaType.Number)); Assert.False(result.Value.HasFlag(JsonSchemaType.Object)); } [Fact] public void ParseTypeValue_HandlesArrayWithOnlyInvalidItems_ReturnsNull() { // Test that when "type" array contains only invalid items, it returns null var typeArrayWithOnlyObjects = JsonNode.Parse("""[{"invalid": "object"}, {"another": "object"}]""") as JsonArray; var result = GenAISchemaHelpers.ParseTypeValue(typeArrayWithOnlyObjects); Assert.Null(result); } [Fact] public void ParseTypeValue_HandlesNullNode_ReturnsNull() { var result = GenAISchemaHelpers.ParseTypeValue(null); Assert.Null(result); } [Fact] public void ParseTypeValue_HandlesValidString_ReturnsCorrectType() { var typeString = JsonNode.Parse("\"string\""); var result = GenAISchemaHelpers.ParseTypeValue(typeString); Assert.Equal(JsonSchemaType.String, result); } [Fact] public void ParseTypeValue_HandlesValidArray_ReturnsCorrectTypes() { var typeArray = JsonNode.Parse("""["string", "null"]""") as JsonArray; var result = GenAISchemaHelpers.ParseTypeValue(typeArray); Assert.NotNull(result); Assert.True(result!.Value.HasFlag(JsonSchemaType.String)); Assert.True(result.Value.HasFlag(JsonSchemaType.Null)); } [Fact] public void ParseOpenApiSchema_HandlesUnexpectedTypeObject_ReturnsSchemaWithNullType() { // Test the full ParseOpenApiSchema method with an unexpected "type" field var schemaJson = """ { "properties": { "param1": { "type": "string" }, "param2": { "type": { "description": "This is an object instead of a string" } } } } """; var schemaObj = JsonNode.Parse(schemaJson) as JsonObject; var schema = GenAISchemaHelpers.ParseOpenApiSchema(schemaObj!); Assert.NotNull(schema); Assert.NotNull(schema!.Properties); Assert.Equal(2, schema.Properties.Count); // param1 should be parsed correctly Assert.True(schema.Properties.ContainsKey("param1")); var param1 = schema.Properties["param1"] as OpenApiSchema; Assert.NotNull(param1); Assert.Equal(JsonSchemaType.String, param1!.Type); // param2 should be parsed but with null type (since type is an object) Assert.True(schema.Properties.ContainsKey("param2")); var param2 = schema.Properties["param2"] as OpenApiSchema; Assert.NotNull(param2); Assert.Null(param2!.Type); } }