* Initial plan * Initial plan for SEP-973 implementation Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Implement SEP-973: Add Icon class and icon support to Implementation, Resource, Tool, and Prompt Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Complete SEP-973 implementation with documentation and fix property consistency Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Address code review feedback: improve tests, remove docs, split test files Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Fix tests to use S.T.J. source generator * Styling fixes * Simplify Icons property documentation as suggested in code review Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Rename Icon.Src property to Icon.Source for more .NET-y naming Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Add icon support to McpServerTool infrastructure and attributes Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Cleanup * Refactor icon tests to use Delegate overload instead of MethodInfo pattern Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Change Icon.Sizes property from string to IList<string> per spec update Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> * Add icon support to Prompts and Resources (CreateOptions and Attributes) Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Add client-server integration tests for Icons and WebsiteUrl Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Fix nullability warnings * Revert "Add client-server integration tests for Icons and WebsiteUrl" This reverts commit f37de15569e54e86a0709121c9bdf80c5045511c. * More nullability fixes * Add more tests * Address code review feedback: add Theme property, fix docs, improve test patterns Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> * Update Icon tests to exercise Theme property Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> * Add Theme property assertions to client-server integration tests Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> * Fix nullability --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> Co-authored-by: Mackinnon Buck <mackinnon.buck@gmail.com> Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> Co-authored-by: David Cantú <dacantu@microsoft.com>
95 lines
3.1 KiB
C#
95 lines
3.1 KiB
C#
using ModelContextProtocol.Protocol;
|
|
using System.Text.Json;
|
|
|
|
namespace ModelContextProtocol.Tests.Protocol;
|
|
|
|
public static class IconTests
|
|
{
|
|
[Fact]
|
|
public static void Icon_SerializationRoundTrip_PreservesAllProperties()
|
|
{
|
|
// Arrange
|
|
var original = new Icon
|
|
{
|
|
Source = "https://example.com/icon.png",
|
|
MimeType = "image/png",
|
|
Sizes = new List<string> { "48x48" },
|
|
Theme = "light"
|
|
};
|
|
|
|
// Act - Serialize to JSON
|
|
string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions);
|
|
|
|
// Act - Deserialize back from JSON
|
|
var deserialized = JsonSerializer.Deserialize<Icon>(json, McpJsonUtilities.DefaultOptions);
|
|
|
|
// Assert
|
|
Assert.NotNull(deserialized);
|
|
Assert.Equal(original.Source, deserialized.Source);
|
|
Assert.Equal(original.MimeType, deserialized.MimeType);
|
|
Assert.Equal(original.Sizes, deserialized.Sizes);
|
|
Assert.Equal(original.Theme, deserialized.Theme);
|
|
}
|
|
|
|
[Fact]
|
|
public static void Icon_SerializationRoundTrip_WithOnlyRequiredProperties()
|
|
{
|
|
// Arrange
|
|
var original = new Icon
|
|
{
|
|
Source = "data:image/svg+xml;base64,PHN2Zy4uLjwvc3ZnPg=="
|
|
};
|
|
|
|
// Act - Serialize to JSON
|
|
string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions);
|
|
|
|
// Act - Deserialize back from JSON
|
|
var deserialized = JsonSerializer.Deserialize<Icon>(json, McpJsonUtilities.DefaultOptions);
|
|
|
|
// Assert
|
|
Assert.NotNull(deserialized);
|
|
Assert.Equal(original.Source, deserialized.Source);
|
|
Assert.Equal(original.MimeType, deserialized.MimeType);
|
|
Assert.Equal(original.Sizes, deserialized.Sizes);
|
|
Assert.Null(deserialized.Theme);
|
|
}
|
|
|
|
[Fact]
|
|
public static void Icon_HasCorrectJsonPropertyNames()
|
|
{
|
|
var icon = new Icon
|
|
{
|
|
Source = "https://example.com/icon.svg",
|
|
MimeType = "image/svg+xml",
|
|
Sizes = new List<string> { "any" },
|
|
Theme = "dark"
|
|
};
|
|
|
|
string json = JsonSerializer.Serialize(icon, McpJsonUtilities.DefaultOptions);
|
|
|
|
Assert.Contains("\"src\":", json);
|
|
Assert.Contains("\"mimeType\":", json);
|
|
Assert.Contains("\"sizes\":", json);
|
|
Assert.Contains("\"theme\":", json);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("""{}""")]
|
|
[InlineData("""{"mimeType":"image/png"}""")]
|
|
[InlineData("""{"sizes":"48x48"}""")]
|
|
[InlineData("""{"mimeType":"image/png","sizes":"48x48"}""")]
|
|
public static void Icon_DeserializationWithMissingSrc_ThrowsJsonException(string invalidJson)
|
|
{
|
|
Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<Icon>(invalidJson, McpJsonUtilities.DefaultOptions));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("false")]
|
|
[InlineData("true")]
|
|
[InlineData("42")]
|
|
[InlineData("[]")]
|
|
public static void Icon_DeserializationWithInvalidJson_ThrowsJsonException(string invalidJson)
|
|
{
|
|
Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<Icon>(invalidJson, McpJsonUtilities.DefaultOptions));
|
|
}
|
|
}
|