csharp-sdk/tests/ModelContextProtocol.Tests/Protocol/IconTests.cs
Copilot f28639119b
Implement SEP-973: Icons and metadata support for Implementations, Resources, Tools, and Prompts (#802)
* 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>
2025-10-08 12:23:01 -07:00

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));
}
}